package com.cloudkinto.service.orderoutput.impl;

import cn.afterturn.easypoi.csv.CsvImportUtil;
import cn.afterturn.easypoi.csv.entity.CsvImportParams;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudkinto.common.DicBusinessConstant;
import com.cloudkinto.common.DicBusinessItemConstant;
import com.cloudkinto.common.constant.GlobalConstants;
import com.cloudkinto.common.constant.SysConstant;
import com.cloudkinto.common.error.ErrorEnum;
import com.cloudkinto.common.exception.BizException;
import com.cloudkinto.common.exception.BizExceptionI18;
import com.cloudkinto.common.exception.NotSufficientFundsException;
import com.cloudkinto.common.utils.ExcelUtils;
import com.cloudkinto.common.utils.OrderCodeUtil;
import com.cloudkinto.common.utils.StringsUtil;
import com.cloudkinto.common.utils.TimeUtils;
import com.cloudkinto.common.utils.dict.StaticDict;
import com.cloudkinto.common.web.PageResult;
import com.cloudkinto.common.web.SingleResult;
import com.cloudkinto.dao.*;
import com.cloudkinto.entity.*;
import com.cloudkinto.extentity.StockRecordPageDto;
import com.cloudkinto.extentity.order.LabellaOrderTrackNumberDto;
import com.cloudkinto.extentity.order.OperateRecordAddDto;
import com.cloudkinto.extentity.order.OrderOutPackageInsertDto;
import com.cloudkinto.extentity.order.OrderOutProductAddNewReq;
import com.cloudkinto.extentity.product.MaterialDto;
import com.cloudkinto.extentity.product.ProductCombinationDto;
import com.cloudkinto.extentity.product.ProductSkuAndIdDto;
import com.cloudkinto.service.dic.DicBusinessItemService;
import com.cloudkinto.service.dic.vo.DicItemRes;
import com.cloudkinto.service.email.MailSenderService;
import com.cloudkinto.service.file.FileService;
import com.cloudkinto.service.finance.CompanyAccountService;
import com.cloudkinto.service.finance.vo.IdAndNameEntity;
import com.cloudkinto.service.operate.OperateRecordService;
import com.cloudkinto.service.operate.vo.OperateRes;
import com.cloudkinto.service.order.OrderAmazonVdfService;
import com.cloudkinto.service.order.OrderRakutenService;
import com.cloudkinto.service.order.OrderTiktokService;
import com.cloudkinto.service.orderback.OrderBackService;
import com.cloudkinto.service.orderback.vo.OrderBackAddItem;
import com.cloudkinto.service.orderback.vo.OrderBackAddReq;
import com.cloudkinto.service.orderoutput.OrderOutputService;
import com.cloudkinto.service.orderoutput.importVo.OrderImportErrorVo1;
import com.cloudkinto.service.orderoutput.openapivo.OpenApiOrderOutputAddReq;
import com.cloudkinto.service.orderoutput.openapivo.OpenApiOrderOutputProductAddReq;
import com.cloudkinto.service.orderoutput.vo.*;
import com.cloudkinto.service.product.ProductCombinationService;
import com.cloudkinto.service.product.ProductInfoService;
import com.cloudkinto.service.region.JpRegionService;
import com.cloudkinto.service.shipprice.ShipPriceService;
import com.cloudkinto.service.shop.ShopService;
import com.cloudkinto.service.stock.StockLogService;
import com.cloudkinto.service.stock.StockRecordService;
import com.cloudkinto.service.stock.vo.record.StockRecordPageRes;
import com.cloudkinto.service.storage.StorageService;
import com.cloudkinto.utils.PackageMinTrilateralSum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * <p>
 * service实现类
 * </p>
 *
 * @author 张永远
 * @since 2020-06-04
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)//事务回滚
public class OrderOutputServiceImpl extends ServiceImpl<OrderOutputDao, OrderOutputDo> implements OrderOutputService {
    private static final String SHIPMENT_TYPE_0 = "普通";
    private static final String SHIPMENT_TYPE_1 = "次日达";
    private static final String SHIPMENT_TYPE_2 = "上门安装";
    private static final String ORDER_OUTPUT_TYPE_2 = "FBA转运";
    private static final String ORDER_OUTPUT_TYPE_1 = "一件代发";
    public static final String SHOPIFY_PREFIX = "shopify_";
    @Autowired
    private OrderOutputDao dao;
    @Autowired
    private FileImportRecordDao fileImportRecordDao;
    @Autowired
    private ProductInfoDao productInfoDao;
    @Autowired
    private OrderOutputPackageDao packageDao;
    @Autowired
    private OrderOutputProductDao productDao;
    @Autowired
    private OrderAmazonDao amazonDao;
    @Autowired
    private OrderRakutenService rakutenDao;
    @Autowired
    private ShopDao shopDao;
    @Autowired
    private StorageService storageService;
    @Autowired
    private JpRegionService regionService;
    @Autowired
    private ProductSkuMapDao productSkuMapDao;
    @Autowired
    private StorageDao storageDao;
    @Autowired
    private DicBusinessItemDao dicBusinessItemDao;
    @Autowired
    private DicBusinessItemService dicBusinessItemService;
    @Autowired
    private ShipPriceService mShipPriceService;
    @Autowired
    private StockRecordDao mStockRecordDao;
    @Autowired
    private CompanyDao mCompanyDao;
    @Autowired
    private DimensDao mDimenDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private ShopService shopService;
    @Autowired
    private OperateRecordService operateRecordDao;
    @Autowired
    private CompanyAccountService companyAccountService;
    @Autowired
    private FileService fileService;
    @Autowired
    private OrderBackService orderBackService;
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Autowired
    private MailSenderService mailSenderService;
    @Autowired
    private OrderQoo10Dao qoo10Dao;
    @Autowired
    private FbaStorageDao fbaStorageDao;
    @Autowired
    private CompanyDao companyDao;
    @Autowired
    private StockLogService mStockLogService;
    @Autowired
    private CostRecordDao costRecordDao;
    @Autowired
    private OrderShopifyDao shopifyDao;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    TransactionDefinition transactionDefinition;
    @Autowired
    private OrderYahooDao yahooDao;
    @Autowired
    private StockRecordService stockRecordService;
    @Autowired
    private ProductCombinationService productCombinationService;
    @Autowired
    private ProductInfoService productInfoService;
    @Autowired
    private OrderOutputPackageDetailDao packageDetailDao;
    @Autowired
    private OrderAmazonVdfService vdfService;
    @Autowired
    private OrderInputPackageDao inputOrderPackageDao;
    @Autowired
    private OrderInputProductDao inputOrderProductDao;
    @Autowired
    private OrderTiktokService tiktokOrderService;
    @Autowired
    private TiktokOrderDao orderTiktokDao;

    @Override
    public SingleResult addInit(Long currentUserId, Long companyId) {
        Map<String, Object> map = new HashMap<>();
        map.put("storageList", storageService.getJpList());
        map.put("regionList", regionService.getList(new HashMap<>()));
        map.put("shopList", shopService.selectShopListInit(currentUserId, companyId));
        map.put("trackList", this.getTrackList());


        //fbaStorage
        List<FbaStorageDo> fbaStorageDos = fbaStorageDao.selectList(null);
        List<Map<String, Object>> fbaStorageList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(fbaStorageDos)) {
            fbaStorageDos.forEach(fbaStorageDo -> {
                Map<String, Object> fbaMap = new HashMap<>();
                fbaMap.put("id", fbaStorageDo.getId());
                fbaMap.put("code", fbaStorageDo.getFbaCode());
                fbaMap.put("name", fbaStorageDo.getFbaName());
                fbaMap.put("address", fbaStorageDo.getAddress());
                fbaMap.put("postCode", fbaStorageDo.getPostCode());
                fbaMap.put("tel", fbaStorageDo.getTelPhone());
                fbaStorageList.add(fbaMap);
            });
        }
        map.put("fbaStorageList", fbaStorageList);

        List<Map> productTypeList = new ArrayList<>();
        LambdaQueryWrapper<DicBusinessItemDo> wrapperProductType = new LambdaQueryWrapper<>();
        wrapperProductType.eq(DicBusinessItemDo::getDicBusinessId, DicBusinessConstant.productType);
        List<DicBusinessItemDo> businessItemDoList = dicBusinessItemDao.selectList(wrapperProductType);
        if (!CollectionUtils.isEmpty(businessItemDoList)) {
            for (DicBusinessItemDo businessItemDo : businessItemDoList) {
                Map mapProductType = new HashMap();
                mapProductType.put("id", businessItemDo.getId());
                mapProductType.put("value", businessItemDo.getDicItemValue());
                productTypeList.add(mapProductType);
            }
        }
        map.put("productTypeList", productTypeList);

        return SingleResult.success(map);
    }

    /**
     * 根据尺寸获取最合适的耗材信息
     *
     * @param size
     * @param storageId
     * @param companyId
     * @return
     */
    public MaterialDto getMaterialList(double[] size, Long storageId, Long materialId, Long companyId) {
        Map<String, String> map = new HashMap<>();
        map.put("companyId", companyId + "");
        if (size != null) {
            map.put("longest", size[0] + "");
            map.put("minor", size[1] + "");
            map.put("shortest", size[2] + "");
        }
        map.put("storageId", storageId + "");
        map.put("goodQuantity", "1");
//        if (materialId != null) {
//            map.put("id", materialId + "");
//        }
        List<MaterialDto> list = productInfoDao.getMaterialList(map);
        if (list.isEmpty()) {
            //没有合适的耗材
            return null;
        } else {
            if (materialId != null) {
                for (MaterialDto materialDto : list) {
                    if (materialId.equals(materialDto.getId())) {
                        return materialDto;
                    }
                }
            }
            return list.get(0);
        }
    }


    /**
     * 生成包裹明细 不会删除 原先的包裹明细 add 方法 和 导出快递单方法用
     *
     * @param orderOutputDo
     * @param storageDo
     * @param currentUserId
     */
    private void dealwithPrintLabelPackageInfo(OrderOutputDo orderOutputDo, StorageDo storageDo, Long currentUserId) {
        List<OrderOutputPackageDetailDo> packageDetailDoList = this.dealwithPrintLabelPackageInfo(null, null, orderOutputDo, storageDo, currentUserId, false);
        for (OrderOutputPackageDetailDo orderOutputPackageDetailDo : packageDetailDoList) {
            packageDetailDao.insert(orderOutputPackageDetailDo);
        }
    }


    /**
     * 生成包裹明细 当编辑时 传true（deleteFlag）
     *
     * @param packageList
     * @param orderOutputDo
     * @param storageDo
     * @param currentUserId
     * @param deleteFlag    会删除之前 旧包裹，已拣货的不要传true
     */
    private List<OrderOutputPackageDetailDo> dealwithPrintLabelPackageInfo(List<OrderOutputPackageDo> packageList, List<OrderOutputProductDo> productDoList, OrderOutputDo orderOutputDo, StorageDo storageDo, Long currentUserId, boolean deleteFlag) {
        if (productDoList == null || productDoList.isEmpty()) {
            QueryWrapper<OrderOutputProductDo> wrapper = new QueryWrapper<>();
            wrapper.eq("order_id", orderOutputDo.getId());
            wrapper.orderByDesc("count");
            productDoList = productDao.selectList(wrapper);
        } else {
            productDoList.sort(Comparator.comparing(OrderOutputProductDo::getCount).reversed());
        }
        if (packageList == null) {
            QueryWrapper<OrderOutputPackageDo> wrapper1 = new QueryWrapper<>();
            wrapper1.eq("order_output_id", orderOutputDo.getId());
            packageList = packageDao.selectList(wrapper1);
        }
        return this.splitPackageInfo(packageList.get(0).getId(), productDoList, orderOutputDo, storageDo.getSupportShip(), currentUserId, deleteFlag);
    }

    /**
     * 把包裹拆分发货
     *
     * @param productDoList
     * @param supportShip
     * @param updateBy
     */
    private List<OrderOutputPackageDetailDo> splitPackageInfo(Long packageId, List<OrderOutputProductDo> productDoList, OrderOutputDo et, String supportShip, Long updateBy, boolean deleteFlag) {
        if (!"1".equals(supportShip)) {
            return new ArrayList<>();
        }

        //捆包完多个个包裹
        LambdaQueryWrapper<OrderOutputPackageDetailDo> lambdaDeleteWrapper = new LambdaQueryWrapper<>();
        lambdaDeleteWrapper.eq(OrderOutputPackageDetailDo::getPackageId, packageId);
        lambdaDeleteWrapper.eq(OrderOutputPackageDetailDo::getOrderOutputId, et.getId());
        List<OrderOutputPackageDetailDo> packageDetailDoList = new ArrayList<>();
        if (deleteFlag) {
            //删除之前的
            packageDetailDao.delete(lambdaDeleteWrapper);
        }
//        else {
//            packageDetailDoList = packageDetailDao.selectList(lambdaDeleteWrapper);
//            if (!packageDetailDoList.isEmpty()) {
//                return packageDetailDoList;
//            }
//        }
        //是否分包 temu平台支持 带面单创建订单
        boolean split = !StringUtils.isNotBlank(et.getTrackNumber());
        List<Long> productIds = productDoList.stream().map(OrderOutputProductDo::getProductId).distinct().collect(Collectors.toList());
        Map<Long, ProductInfoDo> productmMap = new HashMap<>();
        if (!productIds.isEmpty()) {
            List<ProductInfoDo> productBeans = productInfoDao.selectList(new LambdaQueryWrapper<ProductInfoDo>()
                    .in(ProductInfoDo::getId, productIds));
            productmMap = productBeans.stream().collect(Collectors.toMap(ProductInfoDo::getId, i -> i, (v1, v2) -> v1));
        }
        packageDetailDoList = this.getPackageSizeInfoCount(productDoList, split, et.getTrackId(), et.getStorageId(), et.getCompanyId(), productmMap);
        if (StringUtils.isNotBlank(et.getTrackNumber())) {
            for (OrderOutputPackageDetailDo orderOutputPackageDetailDo : packageDetailDoList) {
                orderOutputPackageDetailDo.setTrackNumber(et.getTrackNumber());
            }
        }
        this.insertPackageDetail(packageDetailDoList, et.getId(), et.getStorageId(), packageId, et.getCompanyId(), updateBy);
        return packageDetailDoList;
    }

    /**
     * 保存 捆包分包详情表
     *
     * @param packageDetailDoList
     * @param orderOutputId
     * @param packageId
     * @param userId
     */
    public void insertPackageDetail(List<OrderOutputPackageDetailDo> packageDetailDoList, Long orderOutputId, Long storageId, Long packageId, Long companyId, Long userId) {
//        LambdaQueryWrapper<OrderOutputPackageDetailDo> lambdaDeleteWrapper = new LambdaQueryWrapper<>();
//        lambdaDeleteWrapper.eq(OrderOutputPackageDetailDo::getPackageId, packageId);
//        lambdaDeleteWrapper.eq(OrderOutputPackageDetailDo::getOrderOutputId, orderOutputId);
//        packageDetailDao.delete(lambdaDeleteWrapper);

        for (OrderOutputPackageDetailDo packageDo : packageDetailDoList) {
            //保存 捆包分包详情表
            packageDo.setPackageId(packageId);
            packageDo.setOrderOutputId(orderOutputId);
            packageDo.setCount(1);
            packageDo.setCreateBy(userId);
            packageDo.setCreateTime(new Date());
//            packageDetailDao.insert(packageDo);
        }
    }


    /**
     * 设置 耗材长宽高
     *
     * @param packageDo
     * @param storageId
     * @param companyId
     */
    public void setPackageDetailMaterialLength(OrderOutputPackageDetailDo packageDo, Long trackId, Long storageId, Long companyId) {
        //黑猫盒子 不选耗材
        if (DicBusinessItemConstant.yamatoExpressBox.equals(trackId)) {
            return;
        }
        String inSkuId = String.valueOf(packageDo.getInSkuId().charAt(packageDo.getInSkuId().length() - 1)).equals(",") ? packageDo.getInSkuId().substring(0, packageDo.getInSkuId().length() - 1) : packageDo.getInSkuId();
//            String[] skuIdAArr = inSkuId.split(",");
//            String inSkuId = packageDo.getInSkuId();
        double[] size = mShipPriceService.getSizeOrderDesc(packageDo.getLength(), packageDo.getWidth(), packageDo.getHeight());
        //包裹的尺寸
        if (inSkuId.contains(",")) {
            if (packageDo.getMaterialId() != null && packageDo.getMaterialId().intValue() != -1) {
                //说明是纸袋子 纸袋子三边取 包装的三边
                packageDo.setMLength(packageDo.getLength());
                packageDo.setMWidth(packageDo.getWidth());
                packageDo.setMHeight(packageDo.getHeight());
            } else {
                Set<String> skuId = new HashSet<>(Arrays.asList(inSkuId.split(",")));
                Long materialId = null;
                if (skuId.size() == 1) {
                    ProductInfoDo productInfoDo = productInfoDao.selectObject(Long.parseLong(skuId.iterator().next()));
                    if (productInfoDo != null && productInfoDo.getMaterialId() != null) {
                        materialId = productInfoDo.getMaterialId();
                    }
                }
                //一单多件 捆包的必须要耗材 , 如果尺寸没有匹配上 则不用耗材
                MaterialDto material = this.getMaterialList(size, storageId, materialId, companyId);
                if (material != null) {
                    packageDo.setMaterialId(material.getId());
                    if (material.getShortest() == 0) {
                        //说明是纸袋子 纸袋子三边取 包装的三边
                        packageDo.setMLength(packageDo.getLength());
                        packageDo.setMWidth(packageDo.getWidth());
                        packageDo.setMHeight(packageDo.getHeight());
                    } else {
                        packageDo.setMLength(material.getLength());
                        packageDo.setMWidth(material.getWidth());
                        packageDo.setMHeight(material.getHeight());
                    }
                } else {
                    //看三边和选择 假耗材 方便收费
                    double sizeSum = size[0] + size[1] + size[2];
                    ProductInfoDo productInfoDo = productInfoDao.selectOne(new LambdaQueryWrapper<ProductInfoDo>()
                            .eq(ProductInfoDo::getCommonUse, 0)
                            .eq(ProductInfoDo::getWidth, 0.1).eq(ProductInfoDo::getHeight, 0.1).gt(ProductInfoDo::getLength, sizeSum).last(" order by length asc limit 1"));
                    if (productInfoDo == null) {
                        packageDo.setMaterialId(-1L);
                    } else {
                        packageDo.setMaterialId(productInfoDo.getId());
                        packageDo.setMLength(packageDo.getLength());
                        packageDo.setMWidth(packageDo.getWidth());
                        packageDo.setMHeight(packageDo.getHeight());
                    }
                }
            }
        } else {
            //一单一件
            ProductInfoDo productInfoDo = productInfoDao.selectObject(Long.parseLong(inSkuId));
            if (productInfoDo.getMaterialId() != null) {
                //改版 如果指定了 耗材 则只用这个 耗材
                ProductInfoDo material = productInfoDao.selectById(productInfoDo.getMaterialId());
                if (material != null) {
                    packageDo.setMaterialId(material.getId());
                    if (material.getLength() == 0 || material.getWidth() == 0 || material.getHeight() == 0) {
//                        //说明是纸袋子 纸袋子三边取 包装的三边
                        packageDo.setMLength(packageDo.getLength());
                        packageDo.setMWidth(packageDo.getWidth());
                        packageDo.setMHeight(packageDo.getHeight());
                    } else {
                        packageDo.setMLength((double) material.getLength());
                        packageDo.setMWidth((double) material.getWidth());
                        packageDo.setMHeight((double) material.getHeight());
                    }
                }
//                MaterialDto material = this.getMaterialList(null, storageId, productInfoDo.getMaterialId(), companyId);
//                if (material == null) {
//                    material = this.getMaterialList(size, storageId, null, companyId);
//                }
//                if (material != null) {
//                    packageDo.setMaterialId(material.getId());
//                    if (material.getShortest() == 0) {
//                        //说明是纸袋子 纸袋子三边取 包装的三边
//                        packageDo.setMLength(packageDo.getLength());
//                        packageDo.setMWidth(packageDo.getWidth());
//                        packageDo.setMHeight(packageDo.getHeight());
//                    } else {
//                        packageDo.setMLength(material.getLength());
//                        packageDo.setMWidth(material.getWidth());
//                        packageDo.setMHeight(material.getHeight());
//                    }
//                } else {
//                    packageDo.setMaterialId(-1L);
//                }
            }
        }
    }

    @Override
    public synchronized String add(OrderOutputAddReq req, Long userId) {
        Long trackId = req.getTrackId();
        String value = null;
        if (req.getShipmentType() == null) req.setShipmentType(0);
        sufficientFundsCheck(req.getCompanyId());
        value = addCheck(req);
        if (value != null) return value;
        OrderOutputDo entityDo = new OrderOutputDo();
        BeanUtils.copyProperties(req, entityDo);
        entityDo.setOrderNo(entityDo.getOrderNo().trim());

//        entityDo.setOrderType(1);//一件代发
//         if (StringUtils.isEmpty(req.getArea())) {
        JpRegionDo regionDo = regionService.getRegionDoByPostCode(req.getPostCode());
        if (regionDo != null) {
            entityDo.setArea(regionDo.getName());
            entityDo.setAreaId(regionDo.getId());
            // }
        }
        //判断是一单一件还是一单多件
        int count = 0;
        for (OrderOutputProductAddReq orderOutputProductAddReq : req.getPackageList().get(0).getProductList()) {
            count += orderOutputProductAddReq.getCount();
        }
        entityDo.setOrderType(count > 1 ? 2 : 1);
        handlerAddBefore(entityDo, userId);
        String regEx = "[^0-9||-||^０-９||－]";
        Pattern p = Pattern.compile(regEx);

        if (StringUtils.isNotBlank(req.getPostCode())) {
            entityDo.setPostCode(req.getPostCode().trim().replaceAll("\\n", "").replaceAll("\\\"", "").replaceAll(",", "").replaceAll("，", ""));
            Matcher m = p.matcher(entityDo.getPostCode());
            String post2 = m.replaceAll("").trim();
            entityDo.setPostCode(post2);
        }
        if (StringUtils.isNotBlank(req.getTelPhone())) {
            entityDo.setTelPhone(req.getTelPhone().trim().replaceAll("\\n", "").replaceAll("\\\"", "").replaceAll(",", "").replaceAll("，", "").replaceAll("\\+81", ""));
            Matcher m1 = p.matcher(entityDo.getTelPhone());
            String post1 = m1.replaceAll("").trim();
            entityDo.setTelPhone(post1.trim());
        }
        if (StringUtils.isNotBlank(entityDo.getAddress())) {
            entityDo.setAddress(entityDo.getAddress().replaceAll("\n", "").replaceAll("\"", "").replaceAll("日本", "").replaceAll(",", "").replaceAll("，", "").replaceAll(" 　", "").replaceAll(" ", ""));
            if (StringUtils.isNotBlank(entityDo.getArea())) {
                if (entityDo.getAddress().endsWith(entityDo.getArea())) {
                    entityDo.setAddress(entityDo.getAddress().replaceAll(entityDo.getArea(), ""));
                }
            }
        }
        if (StringUtils.isNotBlank(entityDo.getArea())) {
            entityDo.setArea(entityDo.getArea().replaceAll("\n", "").replaceAll("\"", "").replaceAll(",", "").replaceAll("，", "").replaceAll(" 　", ""));
        }
        if (StringUtils.isNotBlank(entityDo.getReceiverName()))
            entityDo.setReceiverName(entityDo.getReceiverName().replaceAll("\n", "").replaceAll("\"", "").replaceAll(",", "").replaceAll("，", "").replaceAll(" 　", ""));
        if (StringUtils.isNotBlank(entityDo.getTelPhone()))
            entityDo.setTelPhone(entityDo.getTelPhone().replaceAll("\n", "").replaceAll("\"", "").replaceAll(",", "").replaceAll("，", "").replaceAll(" 　", ""));
        if (StringUtils.isNotBlank(req.getDeliveryDate())) {
            Date deliveryDate = TimeUtils.parseDate(req.getDeliveryDate());
            entityDo.setDeliveryDate(deliveryDate);
            //指定次日配达，把订单改成次日达订单
            Date currentDate = TimeUtils.parseDate(TimeUtils.getCurrentDateFormat());
            int currentHour = Integer.parseInt(TimeUtils.getCurrentDateFormat("HH"));
            if (currentHour < 12) {
                if (deliveryDate.getTime() - currentDate.getTime() <= 24 * 60 * 60 * 1000) {
                    req.setDeliveryDate(TimeUtils.getCurrentDateFormat(1));
                    req.setShipmentType(1);
                }
            } else {
                if (deliveryDate.getTime() - currentDate.getTime() <= 48 * 60 * 60 * 1000) {
                    req.setDeliveryDate(TimeUtils.getCurrentDateFormat(2));
                    req.setShipmentType(1);
                }
            }
            if (TimeUtils.parseDate(req.getDeliveryDate()).getTime() - System.currentTimeMillis() > 1000 * 60 * 60 * 24 * 7) {
                return StringsUtil.createI18Message(SysConstant.MAX_DELIVERY_DAY_14);
            }
        }
        if (StringUtils.isNotBlank(req.getDeliveryTime()) && !req.getDeliveryTime().equals("-")) {
            entityDo.setDeliveryTime(req.getDeliveryTime());
        }
        //插入OrderOutputDao所以在后台的出库就可以看到出库单
        save(entityDo);
        value = handlerAddProduct(req.getPackageList().get(0).getProductList(), entityDo, userId);
        if (value != null) {
            dao.deleteById(entityDo.getId());
            return value;
        }

        threadPoolTaskExecutor.execute(() -> {

            String value1 = handlerAddAfter(entityDo, req);
            //日志操作
            if (value1 == null) {
                //生成包裹明细
                StorageDo storageDo = storageDao.selectById(entityDo.getStorageId());
                this.dealwithPrintLabelPackageInfo(entityDo, storageDo, userId);
                if (trackId != null && trackId.equals(entityDo.getTrackId())) {
                    DicBusinessItemDo itemDo = dicBusinessItemDao.selectById(trackId);
                    operateRecordDao.operateAddRecordAndValue(SysConstant.OPERATE_CREATE_ORDER_TRACK, itemDo != null ? itemDo.getDicItemValue() : "未知渠道", entityDo.getId(), userId, 3);
                } else {
                    operateRecordDao.operateAddRecord(SysConstant.OPERATE_CREATE_ORDER, entityDo.getId(), userId, 3);
                }
//                operateRecord("创建", entityDo.getId(), userId);
            } else {
//                operateRecord("创建异常", entityDo.getId(), userId);
                operateRecordDao.operateAddRecord(SysConstant.OPERATE_CREATE_ERROR_ORDER, entityDo.getId(), userId, 3);
            }
        });


        return value;
    }

    final String openApiOrderNoKey = "OpenApiOrderNoSet";


    @Override
    public String openApiAddCatchExcption(OpenApiOrderOutputAddReq req, Long companyId, Long userId) {
        String value = checkOrderNo(req.getOrderNo().trim(), companyId);
        if (value != null) {
            return null;
        }
        try {
            this.openApiAddNotCheckNo(req, companyId, userId);
        } catch (Exception e) {
            e.printStackTrace();
            return StringsUtil.createI18Message(e.getMessage());
        }
        return null;
    }


    @Override
    public SingleResult openApiAdd(OpenApiOrderOutputAddReq req, Long companyId, Long userId) {
        return openApiAdd(req, companyId, userId, true);
    }

    public void openApiAddNotCheckNo(OpenApiOrderOutputAddReq req, Long companyId, Long userId) {
        openApiAdd(req, companyId, userId, false);
    }


    @Override
    public SingleResult openApiAdd(OpenApiOrderOutputAddReq req, Long companyId, Long userId, boolean checkOrderNo) {
        if (companyId == null) {
            throw new BizException(SysConstant.Login_Error_Company);
        }
        long currency = System.currentTimeMillis();
        //将订单号放入redis zset 中 去重
        Double time = redisTemplate.opsForZSet().score(openApiOrderNoKey, req.getOrderNo());
        if (time != null && (currency - time) < 30 * 1000) {
            throw new BizException("订单:" + req.getOrderNo() + "短时间内重复推单,请等待30秒继续推该单");
        }
        //加到redis 中
        redisTemplate.opsForZSet().add(openApiOrderNoKey, req.getOrderNo(), currency);

        log.debug("API推单" + req.getOrderNo());
        log.debug(JSONObject.toJSONString(req));
        String value = null;
        if (req.getShipmentType() == null) req.setShipmentType(0);
        sufficientFundsCheck(companyId);
        if (checkOrderNo)
            value = checkOrderNo(req.getOrderNo().trim(), companyId);
        if (value != null) {
            redisTemplate.opsForZSet().remove(openApiOrderNoKey, req.getOrderNo());
            throw new BizExceptionI18(StringsUtil.createI18Message(value));
        }

        if (StringUtils.isBlank(req.getPostCode())) {
            redisTemplate.opsForZSet().remove(openApiOrderNoKey, req.getOrderNo());
            throw new BizExceptionI18(StringsUtil.createI18Message("缺少邮编"));
        }
        if (StringUtils.isBlank(req.getAddress())) {
            redisTemplate.opsForZSet().remove(openApiOrderNoKey, req.getOrderNo());

            throw new BizExceptionI18(StringsUtil.createI18Message("缺少收货地址"));
        }
        if (req.getProductList() == null || req.getProductList().size() < 1) {
            redisTemplate.opsForZSet().remove(openApiOrderNoKey, req.getOrderNo());
            throw new BizExceptionI18(StringsUtil.createI18Message("缺少发货产品"));
        }
        String value2 = checkTrackWay(req.getStorageId(), req.getCod(), req.getTrackId(), req.getShipmentType());
        if (value2 != null) {
            redisTemplate.opsForZSet().remove(openApiOrderNoKey, req.getOrderNo());
            throw new BizExceptionI18(StringsUtil.createI18Message(value2));
        }
        OrderOutputDo entityDo = new OrderOutputDo();
        BeanUtils.copyProperties(req, entityDo);
//        entityDo.setOrderType(1);//一件代发
        entityDo.setCompanyId(companyId);
        // if (StringUtils.isEmpty(req.getArea())) {
        JpRegionDo regionDo = regionService.getRegionDoByPostCode(req.getPostCode());
        if (regionDo != null) {
            entityDo.setArea(regionDo.getName());
            entityDo.setAreaId(regionDo.getId());
        }
        // }
        String regEx = "[^0-9||-||^０-９||－]";
        Pattern p = Pattern.compile(regEx);
        entityDo.setPostCode(this.checkPostCode(req.getPostCode()));

        if (StringUtils.isNotBlank(req.getTelPhone())) {
            entityDo.setTelPhone(req.getTelPhone().trim().replaceAll("\\n", "").replaceAll("\\\"", "").replaceAll(",", "").replaceAll("，", "").replaceAll("\\+81", ""));
            Matcher m1 = p.matcher(entityDo.getTelPhone());
            String post1 = m1.replaceAll("").trim();
            entityDo.setTelPhone(post1.trim());
        }
        if (StringUtils.isNotBlank(entityDo.getAddress()))
            entityDo.setAddress(entityDo.getAddress().replaceAll("\n", "").replaceAll("\"", "").replaceAll(",", "").replaceAll("，", "").replaceAll(" 　", ""));
        if (StringUtils.isNotBlank(entityDo.getAddress())) {
            if (entityDo.getAddress().startsWith("JP")) {
                entityDo.setAddress(entityDo.getAddress().replaceFirst("JP", ""));
            }
            entityDo.setAddress(entityDo.getAddress().replaceAll("\n", "").replaceAll("\"", "").replaceAll("日本", "").replaceAll(",", "").replaceAll("，", "").replaceAll(" 　", "").replaceAll(" ", ""));
            if (StringUtils.isNotBlank(entityDo.getArea())) {
                if (entityDo.getAddress().endsWith(entityDo.getArea())) {
                    entityDo.setAddress(entityDo.getAddress().replaceAll(entityDo.getArea(), ""));
                }
            }
        }
        if (StringUtils.isNotBlank(entityDo.getArea())) {
            entityDo.setArea(entityDo.getArea().replaceAll("\n", "").replaceAll("\"", "").replaceAll(",", "").replaceAll("，", "").replaceAll(" 　", ""));
            entityDo.setArea(StringsUtil.getJpAreaByEnglishCode(entityDo.getArea()));
        }
        if (StringUtils.isNotBlank(entityDo.getReceiverName()))
            entityDo.setReceiverName(entityDo.getReceiverName().replaceAll("\n", "").replaceAll("\"", "").replaceAll(",", "").replaceAll("，", "").replaceAll(" 　", ""));
        if (StringUtils.isNotBlank(entityDo.getTelPhone()))
            entityDo.setTelPhone(entityDo.getTelPhone().replaceAll("\n", "").replaceAll("\"", "").replaceAll(",", "").replaceAll("，", "").replaceAll(" 　", ""));
        if (StringUtils.isNotBlank(req.getDeliveryDate())) {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            try {
                entityDo.setDeliveryDate(dateFormat.parse(req.getDeliveryDate()));
            } catch (ParseException e) {
                e.printStackTrace();
                redisTemplate.opsForZSet().remove(openApiOrderNoKey, req.getOrderNo());
                throw new BizExceptionI18("指定日期格式仅支持 yyyy-MM-dd");
            }
            if (entityDo.getDeliveryDate().getTime() - System.currentTimeMillis() > 1000 * 60 * 60 * 24 * 14) {
                redisTemplate.opsForZSet().remove(openApiOrderNoKey, req.getOrderNo());
                throw new BizExceptionI18(StringsUtil.createI18Message(SysConstant.MAX_DELIVERY_DAY_14));
            }
        }
        if (StringUtils.isNotBlank(req.getCargoOwner()))
            entityDo.setCargoOwner(req.getCargoOwner().replaceAll("\\n", ""));
        if (req.getCargoAddress() != null)
            entityDo.setCargoAddress(req.getCargoAddress().replaceAll("\\n", "").replaceAll("\\\"", "").replaceAll(",", "").replaceAll("，", ""));
        if (StringUtils.isNotBlank(req.getCargoCode())) {
            entityDo.setCargoCode(req.getCargoCode().trim().replaceAll("\\n", "").replaceAll("\\\"", "").replaceAll(",", "").replaceAll("，", ""));
            Matcher m = p.matcher(entityDo.getCargoCode());
            String post2 = m.replaceAll("").trim();
            entityDo.setCargoCode(post2);
        }
        if (req.getCargoCode() != null)
            entityDo.setCargoCode(req.getCargoCode().replaceAll("\\n", ""));
        if (req.getCargoPhone() != null)
            entityDo.setCargoPhone(req.getCargoPhone().replaceAll("\\n", ""));

        handlerAddBefore(entityDo, userId);
        if (req.getTips() != null && (req.getTips().contains("西浓运输") || req.getTips().contains("西濃運輸") || req.getTips().contains("seino"))) {
            entityDo.setTrackId(DicBusinessItemConstant.xinongExpress);
        }

        dao.insert(entityDo);
        List<OrderOutputProductAddReq> productList = handlerProductList(req.getProductList(), companyId);
        value = handlerAddProduct(productList, entityDo, userId);
        if (value != null) {
            redisTemplate.opsForZSet().remove(openApiOrderNoKey, req.getOrderNo());
            dao.deleteById(entityDo.getId());
            return SingleResult.failure(value);
        }
        value = handlerAddAfter(entityDo, null);
        if (value != null) {
            dao.deleteById(entityDo.getId());
            return SingleResult.failure(value);
        }
        //生成包裹明细
        StorageDo storageDo = storageDao.selectById(entityDo.getStorageId());
        this.dealwithPrintLabelPackageInfo(entityDo, storageDo, userId);
        //日志操作
        operateRecordDao.operateAddRecord(SysConstant.OPERATE_API_CREATE_ORDER, entityDo.getId(), userId, 3);
        if (req.getDfOrder() != null) {
            OrderAmazonVdfDo vdfDo = vdfService.addByOrderOutput(req, companyId, entityDo.getShopId());
            entityDo.setPlatform("vdf");
            entityDo.setPlatformNumber(String.valueOf(vdfDo.getId()));
            if ("YAMATO_LTL".equals(req.getDfOrder().getShipMethod())) {
                // res.setTips(StringUtils.isNotBlank(orderAmazonDo.getShipMethodName())?orderAmazonDo.getShipMethodName():orderAmazonDo.getShipMethod());
                entityDo.setTrackId(DicBusinessItemConstant.yamatoExpressYHC);
            } else {
                entityDo.setTrackId(DicBusinessItemConstant.yamatoExpressA);
            }
            if (org.apache.commons.lang3.StringUtils.isNotBlank(req.getDfOrder().getPackingSlipUrl())) {
                entityDo.setTips("需要受领书");
                entityDo.setTrackId(DicBusinessItemConstant.yamatoExpressSLS);
            }
            dao.updateById(entityDo);
        }
//            operateRecord("API创建", entityDo.getId(), userId);
        //创建即发货
//        dealwithOrderSendOut(entityDo,userId);
        //移除
        redisTemplate.opsForZSet().remove(openApiOrderNoKey, req.getOrderNo());
        //每次操作移除 一天之前得单号
//        redisTemplate.opsForZSet().removeRangeByScore(openApiOrderNoKey, DateUtils.stringFormatToDate("2022-01-01").getTime(), DateUtils.passingDate(new Date(), -1).getTime());
        return SingleResult.success(entityDo.getOrderOutputNumber());
    }

    /**
     * 对外接口，发货后，直接添加一条状态为已发货的记录，并扣除库存
     *
     * @param outputDo
     * @param userId
     */
    private void dealwithOrderSendOut(OrderOutputDo outputDo, Long userId) {
        double[] size;
        double shipFee = 1000;
        double originalShipFee = 500;
        double operateFee = 400;
        double taxFee = 0;
        double outFee = 100;
        int packageCount = 1;
        if (outputDo.getStatus() >= DicBusinessItemConstant.outSendOut && outputDo.getStatus() <= DicBusinessItemConstant.orderCutOff) {
            updateById(outputDo);
            return;
        }
        LambdaQueryWrapper<OrderOutputProductDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderOutputProductDo::getOrderId, outputDo.getId());
        //todo 减库存
        List<OrderOutputProductDo> productDoList = productDao.selectList(wrapper);
        int totalCount = 0;

        for (OrderOutputProductDo orderOutputProductDo : productDoList) {
            LambdaQueryWrapper<StockRecordDo> stockWrapper = new LambdaQueryWrapper();
            stockWrapper.eq(StockRecordDo::getProductInfoId, orderOutputProductDo.getProductId()).eq(StockRecordDo::getStorageId, outputDo.getStorageId()).eq(StockRecordDo::getShopId, outputDo.getShopId());
            StockRecordDo stockRecordDo = mStockRecordDao.selectOne(stockWrapper);
            if (stockRecordDo != null) {
                stockRecordDo.setCanSellCount(stockRecordDo.getCanSellCount() - orderOutputProductDo.getCount());
                stockRecordDo.setUpdateTime(new Date());
                totalCount = totalCount + orderOutputProductDo.getCount();
                mStockRecordDao.updateById(stockRecordDo);
                mStockLogService.saveAutoSendOutLog(orderOutputProductDo.getProductId(), outputDo.getShopId(), outputDo.getStorageId(), -orderOutputProductDo.getCount(), stockRecordDo.getCanSellCount(), outputDo.getCompanyId(), outputDo.getOrderNo(), userId);
            }
        }
        //todo 计费
        StorageDo storageDo = storageDao.selectById(outputDo.getStorageId());
        CompanyDo companyDo = mCompanyDao.selectById(outputDo.getCompanyId());
        CompanyAccountDo companyAccountDo = companyAccountService.getOne(new QueryWrapper<CompanyAccountDo>().eq("company_id", companyDo.getId()));

        //此处给个固定值
        outputDo.setShipFee(shipFee);
        outputDo.setOriginShipFee(originalShipFee);
        outputDo.setOperateFee(operateFee);
        //耗材费用
        outputDo.setOutFee(outFee);
        outputDo.setTaxFee((shipFee + operateFee) * 0.1);
        //        Object res = new Object();
//        BeanUtils.copyProperties(entityDo, res);
//        return res;
        double totalFee = outputDo.getShipFee() + outputDo.getOperateFee() + outputDo.getOutFee() + outputDo.getTaxFee();

        if (outputDo.getStatus() < DicBusinessItemConstant.outSendOut || outputDo.getStatus() == DicBusinessItemConstant.problemShipment) {
            outputDo.setStatus(DicBusinessItemConstant.outSendOut);
        }
        outputDo.setTrackNumber("test" + outputDo.getId());
        updateById(outputDo);

        //出库消费记录
        CostRecordDo costRecordDo = new CostRecordDo();
        costRecordDo.setAfterAmount(companyAccountDo.getCompanyAccount());
        costRecordDo.setType(0);//出库类型
        costRecordDo.setContent(outputDo.getOrderOutputNumber() + "订单出库");
        costRecordDo.setCostAmount(totalFee);
        costRecordDo.setShopId(outputDo.getShopId());
        costRecordDo.setCompanyId(String.valueOf(outputDo.getCompanyId()));
        costRecordDo.setThirdId(String.valueOf(outputDo.getId()));
        costRecordDo.setStatus(0);
        costRecordDo.setCreateTime(new Date());
        costRecordDao.insert(costRecordDo);
        //日志操作
        operateRecordDao.operateAddRecord(SysConstant.OPERATE_SEND_ORDER, outputDo.getId(), userId, 3);

//        operateRecord("发货", outputDo.getId(), userId);
    }

    private List<OrderOutputProductAddReq> handlerProductList(List<OpenApiOrderOutputProductAddReq> productList, Long companyId) {
        List<OrderOutputProductAddReq> list = new ArrayList<>();
        if (productList == null || productList.size() < 1) throw new BizExceptionI18(SysConstant.Product_Info_NotNull);
        productList.forEach(openApiOrderOutputProductAddReq -> {
            OrderOutputProductAddReq req = new OrderOutputProductAddReq();
            req.setCount(openApiOrderOutputProductAddReq.getCount());
            ProductInfoDo productInfoDo = null;
            if (openApiOrderOutputProductAddReq.getProductId() == null) {
                LambdaQueryWrapper<ProductInfoDo> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(ProductInfoDo::getCompanyId, companyId).eq(ProductInfoDo::getCommoditySku, openApiOrderOutputProductAddReq.getCommoditySku());
                productInfoDo = productInfoDao.selectOne(wrapper);
            } else {
                productInfoDo = productInfoDao.selectObject(openApiOrderOutputProductAddReq.getProductId());
            }
            if (productInfoDo != null) {
                req.setCommoditySku(productInfoDo.getCommoditySku());
                req.setProductId(productInfoDo.getId());
                req.setStorageSku(productInfoDo.getStorageSku());
                list.add(req);
            } else {
                throw new BizExceptionI18(SysConstant.Product_NotFound, openApiOrderOutputProductAddReq.getCommoditySku());
            }
        });

        return list;

    }


    private void sufficientFundsCheck(Long companyId) {
        if (!companyAccountService.getIsDue(companyId)) {
            throw new NotSufficientFundsException(ErrorEnum.NOT_SUFFICIENT_FUNDS);
        }
    }

    private String handlerAddProduct(List<OrderOutputProductAddReq> orderProductList, OrderOutputDo entityDo, Long userId) {
        OrderOutputPackageDo packageDo = new OrderOutputPackageDo();
        packageDo.setCreateBy(userId);
        packageDo.setOrderOutputId(entityDo.getId());
        packageDo.setCreateTime(new Date());
        packageDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
        packageDao.insert(packageDo);
        int dangerousGood = 0;
        StringBuilder stringBuilder = new StringBuilder();
        StringBuilder stringBuilder2 = new StringBuilder();
        if (orderProductList.size() > 1 && entityDo.getStorageId() == 5)
            return StringsUtil.createI18Message(SysConstant.STORAGE_NOT_SUPPORT_MUTIL_OUT);
        List<OrderOutputProductAddReq> productAddReqfilter = new ArrayList<>(orderProductList.stream().collect(Collectors.toMap(OrderOutputProductAddReq::getProductId, addReq -> addReq, (o1, o2) -> {
            o1.setCount(o1.getCount() + o2.getCount());
            return o1;
        })).values());
        for (OrderOutputProductAddReq productReq : productAddReqfilter) {
            if (productReq.getProductId() == null)
                return StringsUtil.createI18Message(SysConstant.NO_PRODUCT_INFO_ID, productReq.getCommoditySku());
            ProductInfoDo productInfoDo = productInfoDao.selectById(productReq.getProductId());
            if (productInfoDo == null)
                return StringsUtil.createI18Message(SysConstant.NO_PRODUCT_INFO_ID, productReq.getCommoditySku());
            OrderOutputProductDo outputProductDo = new OrderOutputProductDo();
            outputProductDo.setProductId(productReq.getProductId());
            if (productReq.getCount() < 1)
                return StringsUtil.createI18Message(SysConstant.NO_SKU_COUNT_ID, productInfoDo.getCommoditySku());
            outputProductDo.setCount(productReq.getCount());
            outputProductDo.setSku(productReq.getCommoditySku());
            outputProductDo.setPackageId(packageDo.getId());
            outputProductDo.setOrderId(packageDo.getOrderOutputId());
            outputProductDo.setCreateBy(userId);
            outputProductDo.setCreateTime(new Date());
            outputProductDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
            String productSku = "";
            productSku = productInfoDo.getCommoditySku();
            if (productInfoDo.getBattery() == 1) {
                dangerousGood = 2;
            } else if (productInfoDo.getBreakable() == 1) {
                dangerousGood = 1;
            }
            // LambdaQueryWrapper<StockRecordDo> wrapper = new LambdaQueryWrapper();
//            sendOutEntity.getCommoditySku(), sendOutEntity.getShopId(), sendOutEntity.getStorageId()
//             wrapper.eq(StockRecordDo::getShopId, entityDo.getShopId()).eq(StockRecordDo::getStorageId, entityDo.getStorageId()).eq(StockRecordDo::getProductInfoId, outputProductDo.getProductId());
//             StockRecordDo recordBean = mStockRecordDao.selectOne(wrapper);
//             int waitCount = mStockRecordDao.getOrderOutCount(outputProductDo.getProductId(), entityDo.getShopId(), entityDo.getStorageId()) + mStockRecordDao.getOrderOutTurn2FbaCount(outputProductDo.getProductId(), entityDo.getShopId(), entityDo.getStorageId());
            int canUseCount = stockRecordService.getStockCount(entityDo.getCompanyId(), entityDo.getShopId(), entityDo.getStorageId(), outputProductDo.getProductId(), outputProductDo.getCount());
            if (canUseCount < outputProductDo.getCount()) {
                // //查一遍对应的子SKU
                return StringsUtil.createI18Message(SysConstant.Stock_NotEnough, productSku);
                // }
            }
            LambdaQueryWrapper<OrderOutputProductDo> productDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            productDoLambdaQueryWrapper.eq(OrderOutputProductDo::getProductId, productReq.getProductId())
                    .eq(OrderOutputProductDo::getOrderId, entityDo.getId()).eq(OrderOutputProductDo::getPackageId, packageDo.getId()).last("limit 1");
            OrderOutputProductDo productDo = productDao.selectOne(productDoLambdaQueryWrapper);
            if (productDo != null) {
                productDo.setCount(productDo.getCount() + outputProductDo.getCount());
                productDao.updateById(productDo);
            } else {
                productDao.insert(outputProductDo);
            }
            if (stringBuilder.length() > 0) stringBuilder.append(",");
            if (stringBuilder.length() < 460)
                stringBuilder.append(productSku);
            if (stringBuilder2.length() > 0) stringBuilder2.append(",");
            if (stringBuilder2.length() < 460)
                stringBuilder2.append(productInfoDo.getStorageSku());
        }
        // 产品数量过多时需要人工审核，状态改为-1
//        if (productAddReqfilter.size() > SysConstant.OUTPUT_PRODUCT_SIZE_LIMIT) {
//            entityDo.setStatus(DicBusinessItemConstant.outCreateState);
//        }
        String commoditySku = stringBuilder.toString().replaceAll("\n", "").replaceAll("\"", "").replaceAll("，", "");
        if (commoditySku != null && commoditySku.length() > 500) commoditySku.substring(0, 500);
        entityDo.setCommoditySku(commoditySku);
        entityDo.setDangerousGood(dangerousGood);
        if (stringBuilder2.length() > 500) stringBuilder2.substring(0, 500);
        entityDo.setStorageSku(stringBuilder2.toString());
        updateById(entityDo);
        return null;
    }

    /**
     * 验证库存
     *
     * @param companyId
     * @param shopId
     * @param storageId
     * @param productId
     * @param count
     * @param commoditySku
     */
    private void verifyStock(Long companyId, Long shopId, Long storageId, Long productId, int count, String commoditySku) {
        // LambdaQueryWrapper<StockRecordDo> wrapper = new LambdaQueryWrapper<>();
//            sendOutEntity.getCommoditySku(), sendOutEntity.getShopId(), sendOutEntity.getStorageId()
//         wrapper.eq(StockRecordDo::getShopId, shopId).eq(StockRecordDo::getStorageId, storageId).eq(StockRecordDo::getProductInfoId, productId);
        // StockRecordDo recordBean = mStockRecordDao.selectOne(wrapper);
        int[] countArr = new int[2];
//        CompletableFuture<Integer> oneOrder = CompletableFuture.supplyAsync(() -> mStockRecordDao.getOrderOutCount(productId, shopId, storageId), threadPoolTaskExecutor);
//        CompletableFuture<StockRecordDo> stockOrder = CompletableFuture.supplyAsync(() -> mStockRecordDao.selectOne(wrapper), threadPoolTaskExecutor);
//        CompletableFuture<Integer> fbOrder = CompletableFuture.supplyAsync(() -> mStockRecordDao.getOrderOutTurn2FbaCount(productId, shopId, storageId), threadPoolTaskExecutor);
//        oneOrder.thenAccept(i -> countArr[0] = i);
//        fbOrder.thenAccept(i -> countArr[1] = i);
//        CompletableFuture.allOf(oneOrder, stockOrder, fbOrder).join();
//        int waitCount = countArr[0] + countArr[1];
//         int waitCount = mStockRecordDao.getOrderOutCount(productId, shopId, storageId) + mStockRecordDao.getOrderOutTurn2FbaCount(productId, shopId, storageId);
        int canUseCount = stockRecordService.getStockCount(companyId, shopId, storageId, productId, count);
        if (canUseCount < count) {
            throw new BizExceptionI18(SysConstant.Product_Stock_NotEnough, commoditySku);
        }
    }


    public String checkPostCode(String postCode) {
        if (StringUtils.isBlank(postCode)) {
            return "";
        }
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < postCode.length(); i++) {
            String c = postCode.charAt(i) + "";
            if (!c.matches("[0-9０-９-]+")) {
                continue;
            }
            if (c.matches("[０-９]")) {
                builder.append(Integer.parseInt(c));
            } else {
                builder.append(c);
            }
        }
        return builder.toString();
    }

    //新增校验
    private String addCheck(OrderOutputAddReq req) {
        if (!StringUtils.isNotBlank(req.getPostCode())) return StringsUtil.createI18Message("缺少邮编");
        // else if (req.getPostCode().length() != 7) {
        //     if ((req.getPostCode().contains("-") && req.getPostCode().length() == 8)) {
        //     } else {
        //         return StringsUtil.createI18Message("邮编格式不正确");
        //     }
        // }
        req.setPostCode(this.checkPostCode(req.getPostCode()));
        if (!StringUtils.isNotBlank(req.getAddress())) return StringsUtil.createI18Message("缺少收货地址");
        if (req.getShopId() == null) return StringsUtil.createI18Message("缺少店铺");
        if (req.getStorageId() == null) return StringsUtil.createI18Message("缺少仓库");
        if (req.getPackageList() == null || req.getPackageList().size() < 1) {
            return StringsUtil.createI18Message("缺少发货产品");
        }
        if (req.getPackageList().get(0).getProductList() == null || req.getPackageList().get(0).getProductList().size() < 1) {
            return StringsUtil.createI18Message("缺少发货产品");
        }
        String value = checkOrderNo(req.getOrderNo().trim(), req.getCompanyId(), req.getPackageList().get(0).getProductList());
        if (value != null) {
            return StringsUtil.createI18Message(value);
        }
        String value2 = checkTrackWay(req.getStorageId(), req.getCod(), req.getTrackId(), req.getShipmentType());
        if (value2 != null) {
            return StringsUtil.createI18Message(value2);
        }
        return null;
    }

    private String checkTrackWay(Long storageId, Integer cod, Long trackId, Integer shipmentType) {

        if (storageId == 10 || storageId == 11 || storageId == 13 || storageId == 15) {
            if (cod != null && cod != 0) {
                if (trackId == null || trackId.equals(DicBusinessItemConstant.sagawaExpress) ||
                        trackId.equals(DicBusinessItemConstant.yamatoExpressCOD)
                        || trackId.equals(DicBusinessItemConstant.jpostExpressCod)) {

                } else {
                    return StringsUtil.createI18Message("该渠道不支持COD订单");
                }
            }
            if (shipmentType == 1) {
                if (trackId == null || trackId == DicBusinessItemConstant.sagawaExpress || trackId == DicBusinessItemConstant.yamatoExpress || trackId.equals(DicBusinessItemConstant.yamatoExpressA) || trackId.equals(DicBusinessItemConstant.yamatoExpressSmall) || trackId == DicBusinessItemConstant.xinongExpress) {
                } else {
                    return StringsUtil.createI18Message("该渠道不支持次日达订单");
                }
            }
        } else {
            if (trackId != null && (trackId == DicBusinessItemConstant.yamatoExpress
                    || trackId.equals(DicBusinessItemConstant.yamatoExpressA)
                    || trackId.equals(DicBusinessItemConstant.yamatoExpressSmall)
                    || trackId == DicBusinessItemConstant.jpostExpressCod
                    || trackId == DicBusinessItemConstant.jpostExpress
                    || trackId == DicBusinessItemConstant.jpostExpressCom)) {
                return StringsUtil.createI18Message("该仓库不支持该渠道");
            }
            if (cod != null && cod != 0) {
                return StringsUtil.createI18Message("该物仓库不支持COD订单");
            }
        }
        return null;
    }


    //做新增之前要执行的业务定制处理
    private void handlerAddBefore(OrderOutputDo entityDo, Long userId) {
        entityDo.setCreateBy(userId);
        entityDo.setCreateTime(new Date());
        entityDo.setSendDate(new Date());
        entityDo.setStatus(DicBusinessItemConstant.outCreateState);
        entityDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
    }

    //将新增的do转换成要返回的实体
    private String handlerAddAfter(OrderOutputDo entityDo, OrderOutputAddReq req) {
        entityDo.setOrderOutputNumber(OrderCodeUtil.getOrderOutNumber(entityDo.getId()));
        if (StringUtils.isBlank(entityDo.getOrderNo())) {
            entityDo.setOrderNo(OrderCodeUtil.getOrderOutNumber(entityDo.getId()));
        }
        return updateTrackId(entityDo);
    }

    @Override
    public SingleResult updateInit(Long id) {
        OrderOutputDo outputDo = dao.selectById(id);
        if (outputDo.getStatus() > DicBusinessItemConstant.outCreateCheckState) {
            throw new BizExceptionI18(SysConstant.Order_HadDeal);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("storage", storageService.getJpList());
        map.put("region", regionService.getList(new HashMap<>()));

//        LambdaQueryWrapper<StockRecordDo> productInfoWrapper = new LambdaQueryWrapper<>();
//        productInfoWrapper.eq(StockRecordDo::getCompanyId, outputDo.getCompanyId());
////        productInfoWrapper.eq(StockRecordDo::getStorageId, outputDo.getStorageId());
//        productInfoWrapper.eq(StockRecordDo::getShopId, outputDo.getShopId());
//        List<StockRecordDo> stockRecordDos = mStockRecordDao.selectList(productInfoWrapper);
//        List<IdAndNameEntity> productSkuList = new ArrayList<>();
//        for (StockRecordDo stockRecordDo : stockRecordDos) {
//            ProductInfoDo productInfoDo = productInfoDao.selectById(stockRecordDo.getProductInfoId());
//            if (productInfoDo == null) continue;
//            productSkuList.add(new IdAndNameEntity(productInfoDo.getId().intValue(), productInfoDo.getCommoditySku()));
//        }
//        map.put("productSku", productSkuList);
        OrderOutputDetailRes detailRes = detail(id);

        //fbaStorage
        List<FbaStorageDo> fbaStorageDos = fbaStorageDao.selectList(null);
        List<Map> fbaStorageList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(fbaStorageDos)) {
            fbaStorageDos.forEach(fbaStorageDo -> {
                Map fbaMap = new HashMap();
                fbaMap.put("id", fbaStorageDo.getId());
                fbaMap.put("code", fbaStorageDo.getFbaCode());
                fbaMap.put("name", fbaStorageDo.getFbaName());
                fbaMap.put("address", fbaStorageDo.getAddress());
                fbaMap.put("postCode", fbaStorageDo.getPostCode());
                fbaMap.put("tel", fbaStorageDo.getTelPhone());
                fbaStorageList.add(fbaMap);
            });
        }
        map.put("fbaStorageList", fbaStorageList);

        map.put("detail", detailRes);
        return SingleResult.success(map);
    }

    public int getOrderType(List<OrderOutputProductDetail> productList) {
        int count = 0;
        for (OrderOutputProductDetail orderOutputProductAddReq : productList) {
            count += orderOutputProductAddReq.getCount();
        }
        return (count > 1 ? 2 : 1);
    }

    @Override
    public OrderOutputUpdateReq update(OrderOutputUpdateReq req, Long userId) {
        updateCheck(req);
        req.setPostCode(this.checkPostCode(req.getPostCode()));
        OrderOutputDo entityDo = dao.selectById(req.getId());
        if (entityDo.getStatus() > DicBusinessItemConstant.outCreateCheckState) {
            throw new BizExceptionI18(SysConstant.Order_HadDeal);
        }
        if (req.getFileId() != null) {
            fileService.deleteFile(req.getFileId());
            fileService.uploadFile2(req.getFileId(), req.getFileId());
        }

        Long oldTrackId = entityDo.getTrackId();
        double diffPrice = entityDo.getDiffPrice();
        BeanUtils.copyProperties(req, entityDo);
        //修复 原来系统默认选了非最优方案 无差价，再修改订单时没修改物流方式 还是会把差价带过来的bug
        if (entityDo.getTrackId() != null && oldTrackId != null && oldTrackId.equals(entityDo.getTrackId())) {
            entityDo.setDiffPrice(diffPrice);
        }
        handlerUpdateBefore(entityDo, userId);
        entityDo.setOrderType(this.getOrderType(req.getPackageList().get(0).getProductList()));
        //日志操作
        if (StringUtils.isBlank(entityDo.getOrderOutputNumber())) {
            entityDo.setOrderOutputNumber(OrderCodeUtil.getOrderOutNumber(entityDo.getId()));
        }
        operateRecordDao.operateAddRecord(SysConstant.OPERATE_UPDATE_ORDER, entityDo.getId(), userId, 3, JSONObject.toJSONString(entityDo));
        entityDo.setDeliveryTime(req.getDeliveryTime());
        if (StringUtils.isNotBlank(req.getDeliveryDate())) {
            if (TimeUtils.parseDate(req.getDeliveryDate()).getTime() - System.currentTimeMillis() > 1000 * 60 * 60 * 24 * 14) {
                throw new BizExceptionI18(SysConstant.MAX_DELIVERY_DAY_14);
            }
            entityDo.setDeliveryDate(TimeUtils.parseDate(req.getDeliveryDate()));
        } else {
            entityDo.setDeliveryDate(null);
        }
        dao.updateById(entityDo);
        entityDo = dao.selectById(req.getId());
        return handlerUpdateAfter(entityDo, req, userId);
    }

//    private void operateRecord(String operateStr, Long id, Long userId) {
//        OrderOutputDetailRes res = detail(id);
//        OperateRecordDo operateRecordDo = new OperateRecordDo();
//        operateRecordDo.setDeleteFlag(0);
//        operateRecordDo.setThirdId(id);
//        operateRecordDo.setType(3);
//        operateRecordDo.setOperateBy(userId);
//        operateRecordDo.setOperateTime(new Date());
//        operateRecordDo.setContent(operateStr + "了出库订单");
//        operateRecordDo.setRemarks(JSON.toJSONString(res));
//        operateRecordDao.insert(operateRecordDo);
//    }

    @Override
    public String cutOffCatchException(Long id, Long userId, Long companyId) {
        OrderOutputDo entityDo = dao.selectById(id);
        if (entityDo == null || entityDo.getStatus() == null) {
            throw new BizException(SysConstant.No_Data);
        }
        if (entityDo.getStatus().equals(DicBusinessItemConstant.orderCutOff) || entityDo.getStatus().equals(DicBusinessItemConstant.outHasRecovered)) {
            return null;
        }
        try {
            this.cutoff(id, userId, companyId);
        } catch (Exception e) {
            return e.getMessage();
        }
        return null;
    }

    @Override
    public void cutoff(Long id, Long userId, Long companyId) {
        OrderOutputDo entityDo = dao.selectById(id);
        if (entityDo == null || entityDo.getStatus() == null) {
            throw new BizException(SysConstant.No_Data);
        }
        if (entityDo.getStatus() != null && (entityDo.getStatus().equals(DicBusinessItemConstant.orderCutOff) || entityDo.getStatus().equals(DicBusinessItemConstant.outHasRecovered))) {
            throw new BizExceptionI18(SysConstant.OrderHadCutoff);
        }
        if (entityDo.getStatus() > DicBusinessItemConstant.outPushError && entityDo.getStatus() < DicBusinessItemConstant.waitingPickUp) {
            throw new BizExceptionI18(SysConstant.Order_Cannot_Cutoff);
        }
        entityDo.setCutStatus(entityDo.getStatus());
        if (entityDo.getStatus().equals(DicBusinessItemConstant.alreadyPickUp) || entityDo.getStatus().equals(DicBusinessItemConstant.waitingPickUp) || ((entityDo.getStatus().equals(DicBusinessItemConstant.outWaitSendOut) || entityDo.getStatus().equals(DicBusinessItemConstant.outWaitCheckOut)) && entityDo.getPickUpId() != null && entityDo.getPickUpId() != 0)) {
            entityDo.setStatus(DicBusinessItemConstant.orderCutOff);
        } else if (DicBusinessItemConstant.outCreateCheckState.equals(entityDo.getStatus()) || DicBusinessItemConstant.outCreateState.equals(entityDo.getStatus())) {
            //已审核 不收取费用
            entityDo.setStatus(DicBusinessItemConstant.outHasRecovered);
        } else {
            entityDo.setStatus(DicBusinessItemConstant.orderCutOff);
        }
        //日志操作
        operateRecordDao.operateAddRecord(SysConstant.OPERATE_CUTOFF_ORDER, entityDo.getId(), userId, 3);
        if (DicBusinessItemConstant.outHasRecovered.equals(entityDo.getStatus())) {
            operateRecordDao.operateAddRecord(SysConstant.OPERATE_CUTOFF_BACK_ORDER, entityDo.getId(), userId, 3);
        }
        dao.updateById(entityDo);
        threadPoolTaskExecutor.execute(() -> {
            mailSenderService.sendEmail("有新的截单申请", "单号：" + entityDo.getOrderOutputNumber() + "，请及时处理", SysConstant.cloudkintEmail);
        });
        //将该订单信息添加到退货表中
//        handlerOrderBack(entityDo, userId, companyId);
    }

    @Override
    public SingleResult salesReturnInit(Long id) {
        List<JSONObject> list = new ArrayList<>();
        LambdaQueryWrapper<OrderOutputProductDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderOutputProductDo::getOrderId, id);
        List<OrderOutputProductDo> orderOutputProductDoList = productDao.selectList(wrapper);
        if (!CollectionUtils.isEmpty(orderOutputProductDoList)) {
            orderOutputProductDoList.forEach(orderOutputProductDo -> {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("productId", orderOutputProductDo.getProductId());
                jsonObject.put("count", orderOutputProductDo.getCount());
                ProductInfoDo productInfoDo = productInfoDao.selectById(orderOutputProductDo.getProductId());
                if (productInfoDo != null) {
                    jsonObject.put("productName", productInfoDo.getProductName());
                    jsonObject.put("sku", productInfoDo.getCommoditySku());
                }
                list.add(jsonObject);
            });
        }

        return SingleResult.success(list);
    }

    @Override
    public void salesReturn(OrderOutputSalesReturnReq req, Long userId, Long companyId) {
        OrderOutputDo orderOutputDo = dao.selectById(req.getId());

        if (orderOutputDo.getStatus() < DicBusinessItemConstant.outSendOut || orderOutputDo.getStatus() >= DicBusinessItemConstant.outHasRecovered) {
            throw new BizExceptionI18(SysConstant.Order_Cannot_send);
        }

        LambdaQueryWrapper<OrderBackDo> orderBackDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        orderBackDoLambdaQueryWrapper.eq(OrderBackDo::getOrderOutNumber, orderOutputDo.getOrderOutputNumber());
        int count = orderBackService.getBaseMapper().selectCount(orderBackDoLambdaQueryWrapper);
        if (count > 0) {
            throw new BizExceptionI18(SysConstant.Order_Refund_Existed);
        }

        OrderBackAddReq addReq = new OrderBackAddReq();
        addReq.setContactName(orderOutputDo.getReceiverName());
        DicBusinessItemDo businessItemDo = dicBusinessItemDao.selectById(orderOutputDo.getTrackId());
        if (businessItemDo != null) {
            addReq.setTrackName(businessItemDo.getDicItemValue());
        }
        addReq.setOperateFee(orderOutputDo.getOperateFee());
        addReq.setOrderOutNumber(orderOutputDo.getOrderOutputNumber());
        addReq.setShipFee(orderOutputDo.getShipFee());
        addReq.setShopId(orderOutputDo.getShopId());
        addReq.setStorageId(orderOutputDo.getStorageId());
        addReq.setTaxFee(orderOutputDo.getTaxFee());
        addReq.setTelPhone(orderOutputDo.getTelPhone());
        addReq.setTrackNumber(orderOutputDo.getTrackNumber());

        List<OrderBackAddItem> items = new ArrayList<>();
        req.getItems().forEach(orderOutputSalesReturnItem -> {
            OrderBackAddItem orderBackAddItem = new OrderBackAddItem();
            orderBackAddItem.setProductId(orderOutputSalesReturnItem.getProductId());
            orderBackAddItem.setCount(orderOutputSalesReturnItem.getCount());
            items.add(orderBackAddItem);
        });

        addReq.setItems(items);
        orderBackService.add(addReq, userId, companyId);
    }


    private void handlerOrderBack(OrderOutputDo entityDo, Long userId, Long companyId) {
        OrderBackAddReq req = new OrderBackAddReq();
        req.setContactName(entityDo.getReceiverName());
        DicBusinessItemDo businessItemDo = dicBusinessItemDao.selectById(entityDo.getTrackId());
        if (businessItemDo != null) {
            req.setTrackName(businessItemDo.getDicItemValue());
        }
        req.setOperateFee(entityDo.getOperateFee());
        req.setOrderOutNumber(entityDo.getOrderOutputNumber());
        req.setShipFee(entityDo.getShipFee());
        req.setShopId(entityDo.getShopId());
        req.setStorageId(entityDo.getStorageId());
        req.setTaxFee(entityDo.getTaxFee());
        req.setTelPhone(entityDo.getTelPhone());
        req.setTrackNumber(entityDo.getTrackNumber());

        List<OrderBackAddItem> items = new ArrayList<>();
        LambdaQueryWrapper<OrderOutputProductDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderOutputProductDo::getOrderId, entityDo.getId());
        List<OrderOutputProductDo> orderOutputProductDoList = productDao.selectList(wrapper);
        if (!CollectionUtils.isEmpty(orderOutputProductDoList)) {
            for (OrderOutputProductDo orderOutputProductDo : orderOutputProductDoList) {
                OrderBackAddItem item = new OrderBackAddItem();
                item.setCount(orderOutputProductDo.getCount());
                item.setProductId(orderOutputProductDo.getProductId());
                items.add(item);
            }
        }
        req.setItems(items);

        orderBackService.add(req, userId, companyId);
    }

    //编辑校验
    private void updateCheck(OrderOutputUpdateReq req) {
        if (req.getPackageList() == null || req.getPackageList().size() < 1) {
            throw new BizExceptionI18(SysConstant.Order_Lack_ShipProducts);
        }
    }

    //做修改之前要执行的业务定制处理
    private void handlerUpdateBefore(OrderOutputDo entityDo, Long userId) {
        entityDo.setUpdateBy(userId);
        entityDo.setUpdateTime(new Date());
    }

    //做修改之后要执行的业务定制处理
    private OrderOutputUpdateReq handlerUpdateAfter(OrderOutputDo entityDo, OrderOutputUpdateReq updateReq, Long userId) {
        //改版 出库管理 编辑可新增 删除 包裹
        List<Long> leftPackageIds = updateReq.getPackageList().stream().map(OrderOutputPackageUpdateReq::getId).filter(Objects::nonNull).collect(Collectors.toList());
        //先查出 旧包裹
        List<OrderOutputPackageDo> oldPackageList = packageDao.selectList(new LambdaQueryWrapper<OrderOutputPackageDo>().eq(OrderOutputPackageDo::getOrderOutputId, entityDo.getId()));
        //删除 不存在的包裹
        for (int i = 0; i < oldPackageList.size(); i++) {
            if (!leftPackageIds.contains(oldPackageList.get(i).getId())) {
                //删除该包裹 和包裹下的产品
                productDao.delete(new LambdaQueryWrapper<OrderOutputProductDo>().eq(OrderOutputProductDo::getPackageId, oldPackageList.get(i).getId()));
                packageDao.deleteById(oldPackageList.get(i).getId());
                LambdaQueryWrapper<OrderOutputPackageDetailDo> lambdaDeleteWrapper = new LambdaQueryWrapper<>();
                lambdaDeleteWrapper.eq(OrderOutputPackageDetailDo::getPackageId, oldPackageList.get(i).getId());
                lambdaDeleteWrapper.eq(OrderOutputPackageDetailDo::getOrderOutputId, entityDo.getId());
                List<OrderOutputPackageDetailDo> packageDetailDoList = new ArrayList<>();
                packageDetailDao.delete(lambdaDeleteWrapper);
                oldPackageList.remove(i);
                i--;
            }
        }

        StringBuilder stringBuilder = new StringBuilder();
        StringBuilder stringBuilder2 = new StringBuilder();
        List<OrderOutputPackageUpdateReq> packageUpdateReqs = updateReq.getPackageList();
        for (OrderOutputPackageUpdateReq req : packageUpdateReqs) {
            OrderOutputPackageDo packageDo;
            if (req.getId() == null) {
                //说明是新增
                packageDo = new OrderOutputPackageDo();
                BeanUtils.copyProperties(req, packageDo);
                packageDo.setOrderOutputId(entityDo.getId());
                packageDao.insert(packageDo);

            } else {
                //编辑
                packageDo = packageDao.selectById(req.getId());
                if (packageDo == null) {
                    throw new BizExceptionI18(SysConstant.Order_Package_NotMatch);
                }
                BeanUtils.copyProperties(req, packageDo);
                packageDao.updateById(packageDo);

                productDao.delete(new LambdaQueryWrapper<OrderOutputProductDo>().eq(OrderOutputProductDo::getPackageId, req.getId()));
            }
            //处理 产品信息
            this.insertProduct(req.getProductList(), packageDo.getId(), entityDo.getId(), updateReq.getShopId(), updateReq.getStorageId(), stringBuilder, stringBuilder2);
        }
        if (stringBuilder.length() > 500) stringBuilder.substring(0, 500);
        entityDo.setCommoditySku(stringBuilder.toString());
        if (stringBuilder2.length() > 500) stringBuilder2.substring(0, 500);
        entityDo.setStorageSku(stringBuilder2.toString());
        //编辑时，如果前端没有传运输商 就要把这里设置null dao的更新不会更新null字段
        entityDo.setTrackId(updateReq.getTrackId());
        String value = updateTrackId(entityDo);
        if (value != null) {
            throw new BizExceptionI18(value);
        }

        //生成包裹明细 此处更新 需要删除之前旧包裹 deleteFlag 传值 true
        StorageDo storageDo = storageDao.selectById(entityDo.getStorageId());
        List<OrderOutputPackageDetailDo> packageDetailDoList = this.dealwithPrintLabelPackageInfo(null, null, entityDo, storageDo, userId, true);
        for (OrderOutputPackageDetailDo orderOutputPackageDetailDo : packageDetailDoList) {
            packageDetailDao.insert(orderOutputPackageDetailDo);
        }
        return updateReq;
    }

    public void insertProduct(List<OrderOutputProductDetail> productList, Long packageId, Long orderId, Long shopId, Long storageId, StringBuilder stringBuilder, StringBuilder stringBuilder2) {
        for (OrderOutputProductDetail product : productList) {
            ProductInfoDo productInfoDo = productInfoDao.selectById(product.getProductId());
            String commoditySKu = product.getCommoditySku();
            if (productInfoDo != null) commoditySKu = productInfoDo.getCommoditySku();
            OrderOutputProductDo productDo = new OrderOutputProductDo();
            BeanUtils.copyProperties(product, productDo);
            productDo.setPackageId(packageId);
            productDo.setOrderId(orderId);
            verifyStock(productInfoDo.getCompanyId(), shopId, storageId, product.getProductId(), product.getCount(), commoditySKu);
            productDao.insert(productDo);
            if (stringBuilder.length() > 0) {
                stringBuilder.append(",");
            }
            stringBuilder.append(commoditySKu);
            if (stringBuilder2.length() > 0) {
                stringBuilder2.append(",");
            }
            stringBuilder2.append(product.getStorageSku());
        }
    }


    @Override
    public int delete(Long id, Long userId) {
        OrderOutputDo entityDo = dao.selectById(id);
        if (entityDo.getStatus() > DicBusinessItemConstant.outCreateCheckState) {
            throw new BizExceptionI18(SysConstant.Order_Delete_Fair);
        }
        handlerDeleteBefore(entityDo, userId);
        return dao.deleteById(id);
    }

    //做删除之前要执行的业务定制处理
    private void handlerDeleteBefore(OrderOutputDo entityDo, Long userId) {
        entityDo.setDeleteBy(userId);
        entityDo.setDeleteTime(new Date());
        updateById(entityDo);
    }

    @Override
    public OrderOutputDetailRes detail(Long id) {
        OrderOutputDo entityDo = dao.selectById(id);
        OrderOutputDetailRes res = new OrderOutputDetailRes();
        if (entityDo == null) {
            throw new BizExceptionI18(SysConstant.Order_Detail_Notfound);
        }
        BeanUtils.copyProperties(entityDo, res);
        res.setFileUrl(fileService.getFilePath(entityDo.getFileId()));

        //查询日志
        List<OperateRes> operateResList = operateRecordDao.getOperateList(entityDo.getId(), 3);
        res = handlerDetailAfter(entityDo, res);
        res.setOperateResList(operateResList);
        return res;
    }

    //查询明细之后要执行的业务定制处理
    private OrderOutputDetailRes handlerDetailAfter(OrderOutputDo entityDo, OrderOutputDetailRes res) {
        if (shopDao.selectById(entityDo.getShopId()) != null) {
            res.setShop(shopDao.selectById(entityDo.getShopId()).getShopName());
        }
        if (storageDao.selectById(entityDo.getStorageId()) != null) {
            res.setStorage(storageDao.selectById(entityDo.getStorageId()).getStorageName());
        }
        DicBusinessItemDo dic = dicBusinessItemDao.selectById(entityDo.getTrackId());
        if (dic != null) {
            res.setTrackName(StaticDict.Track_Type.getText(dic.getParentId()));
            res.setTrackId(dic.getParentId());
        }
        res.setStatusId(entityDo.getStatus().intValue());
        if (dicBusinessItemDao.selectById(entityDo.getStatus()) != null) {
            int status = entityDo.getStatus().intValue();
            if (status == 161 && entityDo.getCompanyId() == 404) {
                status = 20;
                res.setStatusId(status);
            }
            res.setStatus(dicBusinessItemDao.selectById(status).getDicItemValue());
        }
        res.setReceiverName(entityDo.getReceiverName());
        if (entityDo.getDeliveryDate() != null) res.setDeliveryDate(TimeUtils.formatDate(entityDo.getDeliveryDate()));
        res.setOrderNumber(entityDo.getOrderOutputNumber());
        res.setCargoOwner(entityDo.getCargoOwner());
        res.setCargoAddress(entityDo.getCargoAddress());
        res.setCargoCode(entityDo.getCargoCode());
        res.setCargoPhone(entityDo.getCargoPhone());
//        res.setOrderTypeName(entityDo.getOrderType() != null && entityDo.getOrderType() == 2 ? ORDER_OUTPUT_TYPE_2 : ORDER_OUTPUT_TYPE_1);
        res.setShipmentTypeName(entityDo.getShipmentType() != null && entityDo.getShipmentType() == 1 ? "SHIPMENT_TYPE_1" : "SHIPMENT_TYPE_0");
        //查询对应包裹列表

        //package
        List<OrderOutputPackageDo> packageDoList = packageDao.selectList(new LambdaQueryWrapper<OrderOutputPackageDo>().eq(OrderOutputPackageDo::getOrderOutputId, res.getId()));
        List<OrderOutputPackageDetail> packageResList = new ArrayList<>();
        //product
        List<OrderOutputProductDo> allProductDoList = productDao.selectList(new LambdaQueryWrapper<OrderOutputProductDo>().eq(OrderOutputProductDo::getOrderId, entityDo.getId()));
        //product根据 packageId分类
        Map<Long, List<OrderOutputProductDo>> productMapList = allProductDoList.stream().collect(Collectors.groupingBy(OrderOutputProductDo::getPackageId));
        //统计订单的所有productId
        List<Long> productIds = allProductDoList.stream().map(OrderOutputProductDo::getProductId).collect(Collectors.toList());
        //库存
        Map<String, String> param = new HashMap<>();
        param.put("storageId", entityDo.getStorageId() + "");
        param.put("shopId", entityDo.getShopId() + "");
        if (productIds.size() > 0) {
            param.put("productIds", StringUtils.join(productIds, ","));
        }
        List<StockRecordPageRes> stockList = stockRecordService.getList(param);
        Map<Long, List<StockRecordPageRes>> stockListMap = stockList.stream().collect(Collectors.groupingBy(StockRecordPageRes::getProductInfoId));
        for (OrderOutputPackageDo packageDo : packageDoList) {
            OrderOutputPackageDetail packageDetailRes = new OrderOutputPackageDetail();
            BeanUtils.copyProperties(packageDo, packageDetailRes);
//            //packageDetail
            List<OrderOutputPackageDetail> packageDetailResList = new ArrayList<>();
            List<OrderOutputPackageDetailDo> packageDetailDoList = packageDetailDao.selectList(new LambdaQueryWrapper<OrderOutputPackageDetailDo>().eq(OrderOutputPackageDetailDo::getPackageId, packageDo.getId()));
            KK:
            for (OrderOutputPackageDetailDo orderOutputPackageDetailDo : packageDetailDoList) {
                OrderOutputPackageDetail detail = new OrderOutputPackageDetail();
                BeanUtils.copyProperties(orderOutputPackageDetailDo, detail);
                detail.setSize(orderOutputPackageDetailDo.getLength() + "+" + orderOutputPackageDetailDo.getWidth() + "+" + orderOutputPackageDetailDo.getHeight() + " *" + orderOutputPackageDetailDo.getCount());
                for (OrderOutputPackageDetail orderOutputPackageDetail : packageDetailResList) {
                    if (orderOutputPackageDetail.getWeight() == orderOutputPackageDetailDo.getWeight() && orderOutputPackageDetail.getLength() == orderOutputPackageDetailDo.getLength() && orderOutputPackageDetail.getWidth() == orderOutputPackageDetailDo.getWidth() && orderOutputPackageDetail.getHeight() == orderOutputPackageDetailDo.getHeight()) {
                        orderOutputPackageDetail.setCount(orderOutputPackageDetail.getCount() + orderOutputPackageDetailDo.getCount());
                        continue KK;
                    } else {

                    }
                }
                packageDetailResList.add(detail);
            }
            packageDetailRes.setSize(packageDo.getLength() + "+" + packageDo.getWidth() + "+" + packageDo.getHeight() + " *" + packageDo.getCount());
            // product
            List<OrderOutputProductDetail> productResList = new ArrayList<>();
//            List<OrderOutputProductDo> productDoList = productDao.selectList(new LambdaQueryWrapper<OrderOutputProductDo>()
//                    .eq(OrderOutputProductDo::getPackageId, packageDo.getId()));
            List<OrderOutputProductDo> productDoList = productMapList.get(packageDo.getId());
            if (productDoList != null && productDoList.size() > 0) {
                for (OrderOutputProductDo productDetail : productDoList) {
                    OrderOutputProductDetail productDetailRes = new OrderOutputProductDetail();
                    BeanUtils.copyProperties(productDetail, productDetailRes);
                    ProductInfoDo productInfoDo = productInfoDao.selectById(productDetail.getProductId());
                    if (productInfoDo != null) {
                        productDetailRes.setCommoditySku(productInfoDo.getCommoditySku());
                        productDetailRes.setStorageSku(productInfoDo.getStorageSku());
                        productDetailRes.setCommodityName(productInfoDo.getCommodityName());
                        if (stockListMap.get(productInfoDo.getId()) != null) {
                            productDetailRes.setCanSellCount(stockListMap.get(productInfoDo.getId()).get(0).getCanSellCount() - stockListMap.get(productInfoDo.getId()).get(0).getNoDelivered());
                        } else {
                            productDetailRes.setCanSellCount(0);
                        }
                    }
                    productResList.add(productDetailRes);
                }
                packageDetailRes.setProductList(productResList);
                packageResList.add(packageDetailRes);
//            packageDetailRes.setPackageDetailList(packageDetailResList);
            }
        }
        res.setPackageList(packageResList);
        //分包信息
        res.setPackageDetailList(this.getPackageDetailResList(res.getId()));
        return res;
    }

    private List<OrderOutputPackageDetail> getPackageDetailResList(Long id) {
        List<OrderOutputPackageDetailDo> packageDetailDoList = packageDetailDao.selectList(new LambdaQueryWrapper<OrderOutputPackageDetailDo>().eq(OrderOutputPackageDetailDo::getOrderOutputId, id));
        List<OrderOutputPackageDetail> packageDetailResList = new ArrayList<>();
        if (packageDetailDoList != null && packageDetailDoList.size() > 0) {
            packageDetailResList = packageDetailDoList.stream().map(new Function<OrderOutputPackageDetailDo, OrderOutputPackageDetail>() {
                @Override
                public OrderOutputPackageDetail apply(OrderOutputPackageDetailDo detailDo) {
                    OrderOutputPackageDetail detail = new OrderOutputPackageDetail();
                    List<OrderOutputProductDetail> productResList = new ArrayList<>();
                    BeanUtils.copyProperties(detailDo, detail);
                    if (detailDo.getMaterialId() != null && detailDo.getMaterialId() != -1L) {
                        detail.setLength(detailDo.getMLength());
                        detail.setWidth(detailDo.getMWidth());
                        detail.setHeight(detailDo.getMHeight());
                        ProductInfoDo materialDo = productInfoDao.selectObject(detailDo.getMaterialId());
                        detail.setMaterialSku(materialDo.getCommoditySku());
                    } else {
                        detail.setMaterialSku(detailDo.getMaterialId() == null ? "无需耗材" : "无合适耗材");
                    }
                    if (StringUtils.isNotBlank(detailDo.getInSkuId())) {
                        String[] split = detailDo.getInSkuId().split(",");
                        Map<String, Long> stringLongMap = Arrays.stream(split).collect(Collectors.groupingBy(s -> s, Collectors.counting()));
                        for (String productId : stringLongMap.keySet()) {
                            OrderOutputProductDetail productDetailRes = new OrderOutputProductDetail();
                            if (StringUtils.isBlank(productId)) continue;
                            ProductInfoDo productInfoDo = productInfoDao.selectById(productId);
                            if (productInfoDo != null) {
                                if (stringLongMap.get(productId) == null) {
                                    continue;
                                } else {
                                    productDetailRes.setCount(stringLongMap.get(productId).intValue());
                                }
                                productDetailRes.setCommoditySku(productInfoDo.getCommoditySku());
                                productDetailRes.setStorageSku(productInfoDo.getStorageSku());
                                productDetailRes.setCommodityName(productInfoDo.getCommodityName());
//                                    if (stockListMap.get(productInfoDo.getId()) != null) {
//                                        productDetailRes.setCanSellCount(stockListMap.get(productInfoDo.getId()).get(0).getCanSellCount());
//                                    }
                                productResList.add(productDetailRes);
                            }
                        }
                        detail.setProductList(productResList);
                    }
                    return detail;
                }
            }).collect(Collectors.toList());
        }
        return packageDetailResList;
    }

    public List<IdAndNameEntity> getTrackList() {
        List<IdAndNameEntity> trackList = new ArrayList<>();
        for (StaticDict.Track_Type value : StaticDict.Track_Type.values()) {
            trackList.add(new IdAndNameEntity(value.getValue().intValue(), value.getText()));
        }
        return trackList;
    }

    @Override
    public SingleResult pageInit(Long companyId, Long userId) {
        Map<String, Object> map = new HashMap<>();
        map.put("storageList", storageService.getJpList());

        map.put("trackList", this.getTrackList());

        List<Map> shopList = shopService.selectShopListInit(userId, companyId);
        List<DicItemRes> dicBusinessItemDos = dicBusinessItemService.getDicItemList(DicBusinessConstant.outPutStatus);
        map.put("shopList", shopList);
        map.put("status", dicBusinessItemDos);
        //订单信息
        LambdaQueryWrapper<ProductInfoDo> productInfoDoWrapper = new LambdaQueryWrapper<>();
        productInfoDoWrapper.eq(ProductInfoDo::getCompanyId, companyId);
        List<ProductInfoDo> productInfoDos = productInfoDao.selectList(productInfoDoWrapper);
        List<IdAndNameEntity> productInfoIdList = new ArrayList<>();
        for (ProductInfoDo productInfoDo : productInfoDos) {
            productInfoIdList.add(new IdAndNameEntity(Integer.parseInt(Long.toString(productInfoDo.getId())), productInfoDo.getCommoditySku()));
        }
        map.put("productInfoId", productInfoIdList);
        map.put("productTypeList", dicBusinessItemService.getDicItemList(DicBusinessConstant.productType));
        return SingleResult.success(map);
    }

    @Override
    public List<OrderOutputListRes> getList(Map<String, String> map) {
        QueryWrapper<OrderOutputDo> wrapper = queryBuild(map, "list");
        List<OrderOutputDo> list = this.list(wrapper);
        List<OrderOutputListRes> result = handlerListAfter(list);
        return result;
    }

    @Override
    public PageResult getListPage(Map<String, String> map) {
        QueryWrapper<OrderOutputDo> wrapper = queryBuild(map, "list");
        IPage<OrderOutputDo> page = pageInit(map);
        page = this.page(page, wrapper);
        List<OrderOutputListRes> resList = handlerListAfter(page.getRecords());
        PageResult result = new PageResult(resList, (int) page.getCurrent(), (int) page.getSize(), (int) page.getTotal(), (int) page.getPages());
        result.setMapInfo(countStatus(map));
        return result;
    }

    private Map countStatus(Map<String, String> map) {
        List<Map> result = new ArrayList<>();
        Map mapTotal = new HashMap();
        map.put("status", "");
        QueryWrapper<OrderOutputDo> wrapper = queryBuild(map, "count");
        wrapper.select("status", "count(1) as count").groupBy("status");
        List<Map<String, Object>> list1 = dao.selectMaps(wrapper);

        Map<Long, Integer> statusMap = new HashMap<>();
        for (Map<String, Object> objectMap : list1) {
            statusMap.put(Long.parseLong(objectMap.get("status").toString()), Integer.parseInt(objectMap.get("count").toString()));
        }
        mapTotal.put("count", statusMap.values().stream().mapToInt(Integer::intValue).sum());
        mapTotal.put("name", StringsUtil.createI18Message("全部"));
        result.add(mapTotal);
        List<DicBusinessItemDo> itemDoList = dicBusinessItemService.getOrderOutStatus(DicBusinessConstant.outPutStatus);
        for (DicBusinessItemDo itemDo : itemDoList) {
            Map oneStatusMap = new HashMap();
            oneStatusMap.put("id", itemDo.getId());
            oneStatusMap.put("count", statusMap.getOrDefault(itemDo.getId(), 0));
            oneStatusMap.put("name", StringsUtil.createI18Message(itemDo.getDicItemValue()));
            result.add(oneStatusMap);
        }
        Map map2 = new HashMap();
        map2.put("census", result);
        return map2;
    }

    //查询分页列表之后对列表数据的处理
    private List<OrderOutputListRes> handlerListAfter(List<OrderOutputDo> list) {
        List<OrderOutputListRes> result = new ArrayList<>();
        for (OrderOutputDo orderOutputDo : list) {
            OrderOutputListRes listRes = new OrderOutputListRes();
            BeanUtils.copyProperties(orderOutputDo, listRes);
            StorageDo storageDo = storageDao.selectById(orderOutputDo.getStorageId());
            if (storageDo != null) {
                listRes.setStorageName(storageDo.getStorageName());
            }
            JpRegionDo regionDo = regionService.getRegionDoByPostCode(orderOutputDo.getPostCode());
            if (regionDo != null) {
                listRes.setStopFlag(regionDo.getStopFlag());
                listRes.setStopReason(regionDo.getStopReason());
            }
            FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(orderOutputDo.getFbaStorageId());
            if (fbaStorageDo != null) {
                listRes.setFbaStorageName(fbaStorageDo.getFbaName());
            }
            DicBusinessItemDo dic = dicBusinessItemDao.selectById(orderOutputDo.getTrackId());
            if (dic != null) {
                listRes.setTrackName(StaticDict.Track_Type.getText(dic.getParentId()));
            }
            int status = orderOutputDo.getStatus().intValue();
            if (status == 161 && orderOutputDo.getCompanyId() == 404) {
                status = 20;
            }
            DicBusinessItemDo dicBusinessItemDo = dicBusinessItemDao.selectById(status);
            if (dicBusinessItemDo != null) {

                listRes.setStatus(dicBusinessItemDo.getDicItemValue());
            }
            if (1 == orderOutputDo.getShipmentType()) {
                listRes.setShipmentTypeName("SHIPMENT_TYPE_1");
            } else {
                listRes.setShipmentTypeName("SHIPMENT_TYPE_0");
            }
            listRes.setNumber(orderOutputDo.getOrderOutputNumber());
            listRes.setSendDate(TimeUtils.formatDate(orderOutputDo.getSendDate()));
//            listRes.setPoNumber(orderOutputDo.getPoNumber());
//            listRes.setVolume(getProductVolume(orderOutputDo));
            listRes.setReceiverName(orderOutputDo.getReceiverName());
            StringBuilder stringBuilder = new StringBuilder();
            if (orderOutputDo.getDeliveryDate() != null) {
                String date = TimeUtils.formatDate(orderOutputDo.getDeliveryDate(), "yyyy-MM-dd");
                stringBuilder.append(date);
            }
            if (orderOutputDo.getDeliveryTime() != null) {
                stringBuilder.append(" " + orderOutputDo.getDeliveryTime());
            }
            listRes.setDeliveryDate(stringBuilder.toString());
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.eq("order_output_id", orderOutputDo.getId());
            List<OrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper);
            if (packageDoList == null) continue;
            if (packageDoList.size() > 1) {

            } else if (packageDoList.size() == 1) {
                OrderOutputPackageDo packageDo = packageDoList.get(0);
                Double size = packageDo.getLength() + packageDo.getHeight() + packageDo.getWidth();
                listRes.setThreeSize(new BigDecimal(size).setScale(0, RoundingMode.HALF_UP).intValue());
//                listRes.setShipPrice(getPriceLevel(size) + "cm");
            }
            listRes.setShipPrice(orderOutputDo.getShipFee() + orderOutputDo.getOutFee() + orderOutputDo.getTaxFee() + orderOutputDo.getOperateFee() + "");
            if (StringUtils.isBlank(listRes.getCommoditySku())) {
                QueryWrapper wrapper1 = new QueryWrapper();
                wrapper1.eq("order_id", orderOutputDo.getId());
                List<OrderOutputProductDo> productList = productDao.selectList(wrapper1);
                StringBuilder sb = new StringBuilder();
                for (OrderOutputProductDo productDo : productList) {
                    if (sb.length() > 0) {
                        sb.append(",");
                    }
                    sb.append(productInfoDao.selectById(productDo.getProductId()).getCommoditySku());
                }
                listRes.setCommoditySku(sb.toString());
            }
            result.add(listRes);
        }
        return result;
    }

    private int getPriceLevel(Double size) {
        int[] levelArr = new int[]{55, 60, 80, 100, 120, 140, 160, 170, 180, 200, 220, 240, 260};
        if (size == null || size == 0) return 0;
        for (int i = 0; i < levelArr.length; i++) {
            if (size.intValue() < levelArr[i]) return levelArr[i];
        }
        return 0;
    }

    private String getProductVolume(OrderOutputDo orderOutputDo) {
        double volume = 0;
        double weight = 0;
        LambdaQueryWrapper<OrderOutputPackageDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderOutputPackageDo::getOrderOutputId, orderOutputDo.getId());
        List<OrderOutputPackageDo> packageDoList = packageDao.selectList(wrapper);
        if (!CollectionUtils.isEmpty(packageDoList)) {
            for (OrderOutputPackageDo packageDo : packageDoList) {
                volume += packageDo.getHeight() * packageDo.getWidth() * packageDo.getLength() * packageDo.getCount();
                weight += packageDo.getWeight() * packageDo.getCount();
            }
        }

        BigDecimal b = new BigDecimal(volume / 1000000);
        double f1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        double f2 = new BigDecimal(weight / 1000).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

        return f1 + "/" + f2;

    }

    private IPage<OrderOutputDo> pageInit(Map<String, String> map) {
        IPage<OrderOutputDo> page = new Page();
        page.setSize(StringUtils.isNotBlank(map.get("pageSize")) ? Long.parseLong(map.get("pageSize")) : 10);
        page.setCurrent(StringUtils.isNotBlank(map.get("current")) ? Long.parseLong(map.get("current")) : 1);
        return page;
    }

    private QueryWrapper<OrderOutputDo> queryBuild(Map<String, String> map, String type) {
        QueryWrapper<OrderOutputDo> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(map.get("keyword"))) {
            wrapper.or(orderOutputDoQueryWrapper -> orderOutputDoQueryWrapper.like("order_no", map.get("keyword").trim()).or(true).like("order_output_number", map.get("keyword").trim()).or(true).like("tel_phone", map.get("keyword").trim()).or(true).like("track_number", map.get("keyword").trim()).or(true).like("commodity_sku", map.get("keyword").trim()).or(true).like("storage_sku", map.get("keyword").trim()).or(true).like("receiver_name", map.get("keyword").trim()));
        }
        if (StringUtils.isNotBlank(map.get("orderOutputNumber"))) {
            wrapper.eq("order_output_number", map.get("orderOutputNumber"));
        }
        if (StringUtils.isNotBlank(map.get("orderNo"))) {
            wrapper.eq("order_no", map.get("orderNo"));
        }
        if (StringUtils.isNotBlank(map.get("trackNumber"))) {
            wrapper.eq("track_number", map.get("trackNumber"));
        }
        if (StringUtils.isNotBlank(map.get("orderNoLike"))) {
            wrapper.like("order_no", map.get("orderNoLike"));
        }
        if (StringUtils.isNotBlank(map.get("trackNumberLike"))) {
            wrapper.like("track_number", map.get("trackNumberLike"));
        }
        if (StringUtils.isNotBlank(map.get("commoditySku"))) {
            wrapper.like("commodity_sku", map.get("commoditySku"));
        }
        if (StringUtils.isNotBlank(map.get("receiverName"))) {
            wrapper.like("receiver_name", map.get("receiverName"));
        }
        if (StringUtils.isNotBlank(map.get("telPhone"))) {
            wrapper.eq("tel_phone", map.get("telPhone"));
        }
        if (StringUtils.isNotBlank(map.get("storageSku"))) {
            wrapper.like("storage_sku", map.get("storageSku"));
        }

        if (StringUtils.isNotBlank(map.get("status"))) {
            if (map.get("companyId").equals("404") && map.get("status").equals("20")) {
                wrapper.in("status", 161, 20);
            } else {
                wrapper.eq("status", map.get("status"));
            }
        }
        if (StringUtils.isNotBlank(map.get("dateType"))) {
            String columnName = "create_time";
            if ("2".equals(map.get("dateType"))) {
                //upload_time
                columnName = "upload_time";
            } else if ("3".equals(map.get("dateType"))) {
                columnName = "send_time";
            }
            wrapper.ge(columnName, map.get("startDate"));
            wrapper.le(columnName, map.get("endDate"));
        }

//        if (StringUtils.isNotBlank(map.get("startDate"))) {
//            wrapper.ge("send_date", map.get("startDate"));
//        }
//        if (StringUtils.isNotBlank(map.get("endDate"))) {
//            wrapper.le("send_date", map.get("endDate"));
//        }
        if (StringUtils.isNotBlank(map.get("storageId"))) {
            wrapper.eq("storage_id", map.get("storageId"));
        }
        if (StringUtils.isNotBlank(map.get("trackId"))) {
            List<Long> trackIds = dicBusinessItemService.getIdByParentId(DicBusinessConstant.trackCompany, Long.parseLong(map.get("trackId")));
            wrapper.in("track_id", trackIds);
        }
        if (StringUtils.isNotBlank(map.get("shopId"))) {
            wrapper.eq("shop_id", map.get("shopId"));
        }
        wrapper.eq("company_id", map.get("companyId"));
        if (StringUtils.isNotBlank(map.get("multi"))) {
            if (map.get("multi").equals("1")) {
                wrapper.eq("order_type", 1);
            } else {
                wrapper.eq("order_type", 2);
            }
        }
        if ("list".equals(type)) {
            wrapper.orderByDesc("id");
        }
        return wrapper;
    }

    @Override
    public SingleResult dealwithExcel(MultipartFile file, Integer tempType, Long shopId, Integer storageId, Long userid, Long companyId) {
        if (companyId == 591L) {
            return this.dealwithExcelNew(file, shopId, storageId, userid, companyId);
        }
        //判断redis 10秒内有没有重复处理
        String redisKey = "OrderOut_uploadExcel_SendMsg" + shopId;
        Object o = redisTemplate.opsForValue().get(redisKey);
        if (o != null) {
            throw new BizException(SysConstant.OrderOut_UploadExcel_ERROR);
        }
        if (shopId == null) throw new BizExceptionI18(SysConstant.Order_Send_NoShop);
        if (storageId == null) throw new BizExceptionI18(SysConstant.Order_Send_NoStorage);
        sufficientFundsCheck(companyId);
        redisTemplate.opsForValue().set(redisKey, 1, 60 * 10, TimeUnit.SECONDS);
        if (StringUtils.isEmpty(file.getName())) {
            redisTemplate.delete(redisKey);
            throw new BizExceptionI18(SysConstant.File_Name_Null);
        }
        String originalFilename = file.getOriginalFilename();
        String suffix = file.getOriginalFilename().substring(originalFilename.lastIndexOf(".") + 1);
        if (!GlobalConstants.IMG_TYPE_XLS.equals(suffix.toUpperCase()) &&
                !GlobalConstants.IMG_TYPE_CSV.equals(suffix.toUpperCase())
                && !GlobalConstants.IMG_TYPE_XLSX.equals(suffix.toUpperCase())) {
            redisTemplate.delete(redisKey);
            throw new BizExceptionI18(SysConstant.File_Form_Incorrect);
        }
        InputStream soureFileInputStream = null;
        try {
            soureFileInputStream = file.getInputStream();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        Long fileId = null;
        //将文件保存到服务器
        try {
            //方案二 直接上传到正式路径
            fileId = fileService.uploadFileToFormalPath(soureFileInputStream, originalFilename);
            if (fileId != null && fileId != 0L) {
                fileService.addFileMoreDo(fileId, 0L, "orderOutputSend");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        String fileUrl = fileService.getFilePath(fileId);
        FileImportRecordDo recordDo = new FileImportRecordDo("output", fileId, null, companyId, shopId, 0, 0, new Date(), userid);
        recordDo.setSourceFileUrl(fileUrl);
        recordDo.setDeleteFlag(0);
        fileImportRecordDao.insert(recordDo);
        threadPoolTaskExecutor.execute(() -> {
            int orderCount = 0;
            List<OrderImportErrorVo1> tips = new ArrayList<>();
            List<OrderOutputDo> etList = new ArrayList<>();
            if (tempType == 1) {
                List<OrderOutputExcelImport> excelImportList = null;
                try {
                    excelImportList = ExcelUtils.importExcel(file, 1, 0, OrderOutputExcelImport.class);
                } catch (IOException e) {
                    e.printStackTrace();
                }

                if (excelImportList == null) {
                    excelImportList = new ArrayList<>();
                }
                orderCount = excelImportList.size();
                for (int i = 0; i < excelImportList.size(); i++) {
                    OrderOutputExcelImport excelData = excelImportList.get(i);
                    //配達時間 必须是 - 或者 xx-xx格式
                    if (StringUtils.isNotBlank(excelData.getDeliveryTime()) && (!excelData.getDeliveryTime().equals("午前中") && !excelData.getDeliveryTime().matches("[-]") && !excelData.getDeliveryTime().matches("[0-9０-９][0-9０-９]-[0-9０-９][0-9０-９]時?"))) {
//                        redisTemplate.delete(redisKey);
//                        throw new BizException(SysConstant.Order_UploadFile_Time_Error);
                        tips.add(new OrderImportErrorVo1(StringsUtil.createI18Message(SysConstant.LINE_NUMBER, (i + 2)), StringsUtil.createI18Message(SysConstant.Order_UploadFile_Time_Error)));
                        continue;
                    }
                    if (StringUtils.isBlank(excelData.getPostCode()) && StringUtils.isBlank(excelData.getCommoditySku1()) && StringUtils.isBlank(excelData.getOrderNo()) && StringUtils.isBlank(excelData.getAddress())) {
                        continue;
                    }
                    String value = dealwithExcelData(i + 2, excelData, shopId, storageId, userid);
                    if (value != null) {
                        tips.add(new OrderImportErrorVo1(StringsUtil.createI18Message(SysConstant.LINE_NUMBER, (i + 2)), value));
                    }
                }
            } else {
                List<OrderOutputExcelOldOneImport> excelImportList = null;
                try {
                    excelImportList = ExcelUtils.importExcel(file, 1, 0, OrderOutputExcelOldOneImport.class);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (excelImportList == null) {
                    excelImportList = new ArrayList<>();
                }
                Map<String, List<OrderOutputExcelOldOneImport>> collect = excelImportList.stream().filter(o1 -> StringUtils.isNotBlank(o1.getOrderNo())).collect(Collectors.groupingBy(i -> stringTrim(i.getOrderNo())));
                orderCount = collect.size();
                tips = this.dealwithExcelTempTwo(etList, collect, shopId, storageId, userid, companyId);
            }
            List<OrderImportErrorVo1> errorVo1List = new ArrayList<>(tips);
            Long errorFileId = null;
            if (!errorVo1List.isEmpty()) {
                String fileName = "错误原因—" + file.getOriginalFilename();
                Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), OrderImportErrorVo1.class, errorVo1List);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                InputStream inputStream = null;
                try {
                    workbook.write(bos);
                    bos.flush();
                    inputStream = new ByteArrayInputStream(bos.toByteArray());
                    bos.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                errorFileId = fileService.uploadFileToFormalPath(inputStream, fileName);
            }
            recordDo.setSuccessCount(orderCount - tips.size());
            recordDo.setErrorCount(tips.size());
            recordDo.setStatus(1);
            recordDo.setErrorFileId(errorFileId);
            if (errorFileId != null) {
                String errorFileUrl = fileService.getFilePath(errorFileId);
                recordDo.setErrorFileUrl(errorFileUrl);
            }
            recordDo.setStatus(1);
            fileImportRecordDao.updateById(recordDo);
            redisTemplate.delete(redisKey);
            this.dealExcelDataAfter(etList, userid);

        });
//        if (tips.size() > 0) {
//            return SingleResult.failure("300", SysConstant.IMPORT_OUT_ORDER_SUCCESS_ID, tips, orderCount - tips.size());
//        } else {
//            return SingleResult.success(SysConstant.IMPORT_OUT_ORDER_SUCCESS_ID, null, orderCount);
//        }
        return SingleResult.success("操作成功", "正在处理中,请稍候在 导入记录历史 中查看");
    }

    public List<OrderImportErrorVo1> dealwithExcelTempTwo(List<OrderOutputDo> etList, Map<String, List<OrderOutputExcelOldOneImport>> collect, Long shopId, Integer storageId, Long userid, Long companyId) {

        List<OrderImportErrorVo1> tips = new ArrayList<>();
        //先校验基本格式
        List<String> platformNos = new ArrayList<>(collect.keySet());
        if (platformNos.isEmpty()) {
            return tips;
        }
        List<JpRegionDo> regionDoList = regionService.list();
        Map<String, JpRegionDo> areaMap = regionDoList.stream().collect(Collectors.toMap(JpRegionDo::getName, jpRegionDo -> jpRegionDo));
        //获取所有的产品
        Set<String> skuList = new HashSet<>();
        platformNos.forEach(platformNo -> collect.get(platformNo).forEach(orderOutputExcelImportNew -> skuList.add(orderOutputExcelImportNew.getCommoditySku1().trim().replaceAll("\\n", "").trim().replaceAll(" ", ""))));
        Map<String, Long> skuMap = new HashMap<>();
        if (!skuList.isEmpty()) {
            Map<String, Long> skuMao = productInfoDao.getProductSkuAndIdList(new ArrayList<>(skuList), "commodity_sku", companyId)
                    .stream().collect(Collectors.toMap(ProductSkuAndIdDto::getSku, ProductSkuAndIdDto::getId, (v1, v2) -> v2));
            skuMap.putAll(skuMao);
            List<String> leftStorageSkuList = skuList.stream().filter(sku -> !skuMao.containsKey(sku)).collect(Collectors.toList());
            Map<String, Long> storageSkuMap;
            if (!leftStorageSkuList.isEmpty()) {
                storageSkuMap = productInfoDao.getProductSkuAndIdList(leftStorageSkuList, "storage_sku", companyId)
                        .stream().collect(Collectors.toMap(ProductSkuAndIdDto::getSku, ProductSkuAndIdDto::getId, (v1, v2) -> v2));
                skuMap.putAll(storageSkuMap);
            } else {
                storageSkuMap = new HashMap<>();
            }
            List<String> leftSubSkuMap = leftStorageSkuList.stream().filter(sku -> !storageSkuMap.containsKey(sku)).collect(Collectors.toList());
            if (!leftSubSkuMap.isEmpty()) {
                Map<String, Long> subSkuMap = productInfoDao.getSubProductSkuAndIdList(leftStorageSkuList, companyId).stream().collect(Collectors.toMap(ProductSkuAndIdDto::getSku, ProductSkuAndIdDto::getId, (v1, v2) -> v2));
                skuMap.putAll(subSkuMap);
            }
        }
        //获取所有的组合产品
        Map<Long, List<ProductCombinationDto>> combinationMap = productCombinationService.getCombinationList(companyId);
        LambdaQueryWrapper<OrderOutputDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(OrderOutputDo::getOrderNo, platformNos)
                .ne(OrderOutputDo::getStatus, DicBusinessItemConstant.outHasRecovered)
                .ne(OrderOutputDo::getStatus, DicBusinessItemConstant.orderCutOff)
                .eq(OrderOutputDo::getCompanyId, companyId)
                .select(OrderOutputDo::getOrderNo);
        List<Object> orderNos = baseMapper.selectObjs(wrapper);
        Map<String, List<OrderOutProductAddNewReq>> productReqList = new HashMap<>();
        Map<Long, String> productIdMap = new HashMap<>();
        if (!skuMap.isEmpty()) {
            productIdMap = productInfoService.list(new LambdaQueryWrapper<ProductInfoDo>().select(ProductInfoDo::getId, ProductInfoDo::getCommoditySku).in(ProductInfoDo::getId, skuMap.values()))
                    .stream().collect(Collectors.toMap(ProductInfoDo::getId, ProductInfoDo::getCommoditySku, (v1, v2) -> v2));
        }

        platformNo:
        for (int z = 0; z < platformNos.size(); z++) {
            String platformNo = platformNos.get(z);
            OrderOutputExcelOldOneImport excelData = collect.get(platformNo).get(0);
//                    OrderImportUtilVo importUtilVo = new OrderImportUtilVo(platformNo, excelData.getCommoditySku()
//                            , excelData.getPostCode(), excelData.getAddress(), excelData.getDeliveryDate(), companyId);
            if (StringUtils.isNotBlank(excelData.getCommoditySku2()) || StringUtils.isNotBlank(excelData.getCommoditySku3()) || StringUtils.isNotBlank(excelData.getCommoditySku4())) {
                tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.Order_Import_temp_Error)));
                platformNos.remove(z);
                z--;
                continue;
            }
            if (orderNos.contains(platformNo)) {
                tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.ORDER_NUMBER_EXIST_No_id)));
                platformNos.remove(z);
                z--;
                continue;
            }
            if (StringUtils.isBlank(excelData.getCommoditySku1())) {
                tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.Order_OrderNo_NoSkuMsg_new)));
                platformNos.remove(z);
                z--;
                continue;
            }
            if (StringUtils.isBlank(excelData.getPostCode())) {
                tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message("缺少邮编")));
                platformNos.remove(z);
                z--;
                continue;
            }
            if (StringUtils.isNotBlank(excelData.getReceiverName()) && excelData.getReceiverName().length() > 20) {
                tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.Order_Name_TooLong_Sim)));
                platformNos.remove(z);
                z--;
                continue;
            }
            if (StringUtils.isEmpty(excelData.getAddress())) {
                tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.Order_NoAddress, excelData.getOrderNo())));
                platformNos.remove(z);
                z--;
                continue;
            }

            OrderOutputDo outputDo = new OrderOutputDo();
            outputDo.setSendDate(new Date());
            outputDo.setStatus(DicBusinessItemConstant.outCreateState);
            outputDo.setShopId(shopId);
            outputDo.setCompanyId(companyId);
            if (storageId != null) {
                outputDo.setStorageId((long) storageId);
            }
            String regEx = "[^0-9||-||^０-９||－]";
            Pattern p = Pattern.compile(regEx);
            outputDo.setOrderNo(excelData.getOrderNo().trim().replaceAll("\\n", "").replaceAll("\\\"", "").replaceAll(",", "").replaceAll("，", ""));
            outputDo.setCreateBy(userid);
            outputDo.setCreateTime(new Date());
            outputDo.setPostCode(excelData.getPostCode().trim().replaceAll("\\n", "").replaceAll("\\\"", "").replaceAll(",", "").replaceAll("，", ""));
            Matcher m = p.matcher(outputDo.getPostCode());
            String post2 = m.replaceAll("").trim();
            outputDo.setPostCode(post2);
            if (StringUtils.isNotBlank(excelData.getTelPhone())) {
                outputDo.setTelPhone(excelData.getTelPhone().trim().replaceAll("\\n", "").replaceAll("\\\"", "").replaceAll(",", "").replaceAll("，", "").replaceAll("\\+81", ""));
                Matcher m1 = p.matcher(outputDo.getTelPhone());
                String post1 = m1.replaceAll("").replaceAll("\\+81", "").trim();
                outputDo.setTelPhone(post1.trim());
            }
            String area = stringTrim(excelData.getArea());
            JpRegionDo jpRegionDo = StringUtils.isBlank(area) ? null : areaMap.get(area);
            if (jpRegionDo != null) {
                outputDo.setAreaId(jpRegionDo.getId());
                outputDo.setArea(jpRegionDo.getName());
            } else {
                jpRegionDo = regionService.getRegionDoByPostCode(post2, regionDoList);
                if (jpRegionDo != null) {
                    outputDo.setAreaId(jpRegionDo.getId());
                    outputDo.setArea(jpRegionDo.getName());
                } else {
                    outputDo.setArea(area);
                }
            }
            outputDo.setCreateTime(new Date());
            outputDo.setAddress(excelData.getAddress().replaceAll("\\n", "").replaceAll("\\\"", "").replaceAll(",", "").replaceAll("，", ""));
            if (StringUtils.isNotBlank(excelData.getReceiverName())) {
                outputDo.setReceiverName(excelData.getReceiverName().replaceAll("\\n", "").replaceAll("\\\"", "").replaceAll(",", "").replaceAll("，", ""));
            }
            Date deliveryDate = null;
            if (StringUtils.isNotBlank(excelData.getDeliveryDate())) {
                String pattern = "yyyy/MM/dd";
                if (excelData.getDeliveryDate().contains("-")) {
                    pattern = "yyyy-MM-dd";
                }
                try {
                    deliveryDate = DateUtil.parse(excelData.getDeliveryDate(), pattern);
//                    deliveryDate = TimeUtils.parseDate(excelData.getDeliveryDate(), "yyyy/MM/dd");
                } catch (Exception e) {
                    e.printStackTrace();
                    tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.Order_ErrDateFormat_)));
                    platformNos.remove(z);
                    z--;
                    continue;
                }

                //指定次日配达，把订单改成次日达订单
                Date currentDate = TimeUtils.parseDate(TimeUtils.getCurrentDateFormat());
                int currentHour = Integer.parseInt(TimeUtils.getCurrentDateFormat("HH"));
                if (currentHour < 12) {
                    if (deliveryDate.getTime() - currentDate.getTime() <= 24 * 60 * 60 * 1000) {
                        deliveryDate = TimeUtils.getDateAdd(deliveryDate, 1);
                        excelData.setShipmentType(SHIPMENT_TYPE_1);
                    }
                } else {
                    if (deliveryDate.getTime() - currentDate.getTime() <= 48 * 60 * 60 * 1000) {
                        deliveryDate = TimeUtils.getDateAdd(deliveryDate, 2);
                        excelData.setShipmentType(SHIPMENT_TYPE_1);
                    }
                }
                if (TimeUtils.parseDate(excelData.getDeliveryDate()).getTime() - System.currentTimeMillis() > 1000 * 60 * 60 * 24 * 14) {
                    tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.MAX_DELIVERY_DAY_14)));
                    platformNos.remove(z);
                    z--;
                    continue;
                }
            }

            outputDo.setDeliveryDate(deliveryDate);
            if (StringUtils.isNotBlank(excelData.getDeliveryTime())) {
                outputDo.setDeliveryTime(excelData.getDeliveryTime().replaceAll("时", "").replaceAll("時", ""));
            }
            if (excelData.getTips() != null && (excelData.getTips().contains("西浓") || excelData.getTips().contains("西濃") || excelData.getTips().contains("seino"))) {
                outputDo.setTrackId(DicBusinessItemConstant.xinongExpress);
            }
            outputDo.setTips(excelData.getTips());
            outputDo.setCod(excelData.getCod());
            if (SHIPMENT_TYPE_1.equals(excelData.getShipmentType())) {
                outputDo.setShipmentType(1);
            } else if (SHIPMENT_TYPE_2.equals(excelData.getShipmentType())) {
                outputDo.setShipmentType(0);
                outputDo.setTrackId(StaticDict.Track_Type.YamatoExpressJCB.getValue());
            } else {
                outputDo.setShipmentType(0);
            }

//            save(outputDo);

            List<OrderOutProductAddNewReq> itemAddReqList = new ArrayList<>();
            for (OrderOutputExcelOldOneImport orderOutputExcelImportNew : collect.get(platformNo)) {
                Long productId = skuMap.get(orderOutputExcelImportNew.getCommoditySku1());
                if (productId == null) {
                    tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.Product_NotExist_no_Index, orderOutputExcelImportNew.getCommoditySku1())));
                    platformNos.remove(z);
                    z--;
                    continue platformNo;
                }
                if (!orderOutputExcelImportNew.getCount1().matches("[0-9]+") || Integer.parseInt(orderOutputExcelImportNew.getCount1()) < 1) {//todo
                    tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.Product_QuantityLess_no_Index, orderOutputExcelImportNew.getCommoditySku1())));
                    platformNos.remove(z);
                    z--;
                    continue platformNo;
                }

                if (combinationMap.get(productId) != null) {
                    //说明是组合产品
                    for (ProductCombinationDto productCombinationDto : combinationMap.get(productId)) {
                        OrderOutProductAddNewReq productAddReq = new OrderOutProductAddNewReq();
                        productAddReq.setOrderNo(platformNo);
                        productAddReq.setProductId(productCombinationDto.getChildId());
                        productAddReq.setCommoditySku(productCombinationDto.getCommoditySku());
                        productAddReq.setCount(productCombinationDto.getCount() * Integer.parseInt(orderOutputExcelImportNew.getCount1()));
                        productAddReq.setCreateBy(userid);
                        itemAddReqList.add(productAddReq);
                    }
                } else {
                    OrderOutProductAddNewReq productAddReq = new OrderOutProductAddNewReq();
                    productAddReq.setOrderNo(platformNo);
                    productAddReq.setProductId(productId);
                    productAddReq.setCommoditySku(productIdMap.get(productId));
                    productAddReq.setCount(Integer.parseInt(orderOutputExcelImportNew.getCount1()));
                    productAddReq.setCreateBy(userid);
                    itemAddReqList.add(productAddReq);
                }
            }
            List<OrderOutProductAddNewReq> productAddReqfilter = new ArrayList<>(itemAddReqList.stream().collect(Collectors.toMap(OrderOutProductAddNewReq::getProductId, addReq1 -> addReq1, (o1, o2) -> {
                o1.setCount(o1.getCount() + o2.getCount());
                return o1;
            })).values());
            //验证库存
            if (productAddReqfilter.isEmpty()) {
                tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.Product_Info_NotNull)));
                platformNos.remove(z);
                z--;
                continue;
            }
            int orderType = productAddReqfilter.size() > 1 || productAddReqfilter.get(0).getCount() > 1 ? 2 : 1;
            outputDo.setOrderType(orderType);

            etList.add(outputDo);
            productReqList.put(platformNo, productAddReqfilter);
        }
        //获取所有的仓库sku
        List<Long> productIds = new ArrayList<>();
        for (List<OrderOutProductAddNewReq> orderOutProductAddNewReqs : new ArrayList<>(productReqList.values())) {
            for (OrderOutProductAddNewReq orderOutProductAddNewReq : orderOutProductAddNewReqs) {
                if (productIds.contains(orderOutProductAddNewReq.getProductId())) {
                    continue;
                }
                productIds.add(orderOutProductAddNewReq.getProductId());
            }
        }
        Map<Long, String> storageSkuMap = new HashMap<>();
        Map<Long, ProductInfoDo> productBBMap = new HashMap<>();
        if (!productIds.isEmpty()) {
            storageSkuMap = productInfoDao.getFieldByProductIds(productIds, "storage_sku", companyId).stream().collect(Collectors.toMap(ProductSkuAndIdDto::getId, ProductSkuAndIdDto::getSku));
            LambdaQueryWrapper<ProductInfoDo> productQueryWrapper = new LambdaQueryWrapper<>();
            productQueryWrapper.select(ProductInfoDo::getId, ProductInfoDo::getCommoditySku, ProductInfoDo::getBattery, ProductInfoDo::getBreakable)
                    .in(ProductInfoDo::getId, productIds);
            productBBMap = productInfoDao.selectList(productQueryWrapper).stream().collect(Collectors.toMap(ProductInfoDo::getId, p -> p));
        }
        List<OrderOutPackageInsertDto> packageInsertDtos = new ArrayList<>();
        List<OrderOutProductAddNewReq> productAddReqList = new ArrayList<>();
        List<OperateRecordAddDto> operateRecordDos = new ArrayList<>();
        //再去验证库存
        Map<String, String> map = new HashMap<>();
        map.put("productIds", StringUtils.join(productIds, ","));
        map.put("shopId", String.valueOf(shopId));
        map.put("inStock", "2");
        if (storageId != null && storageId != 0) {
            map.put("storageId", String.valueOf(storageId));
        }
        Map<Long, List<StockRecordPageDto>> storageStockMap = mStockRecordDao.listPage(map).stream().collect(Collectors.groupingBy(StockRecordPageDto::getStorageId));
        //目前 此方法 不支持店铺调货 以及自动选择仓库
//        Map<Long, List<StockRecordPageDto>> pageDtoMap = mStockRecordDao.listPage(map).stream().collect(Collectors.groupingBy(StockRecordPageDto::getProductId));
        order:
        for (int k = 0; k < etList.size(); k++) {
            int dGoods = 0;
            String platformNo = etList.get(k).getOrderNo();
            StringBuilder sku = new StringBuilder();
            StringBuilder storageSku = new StringBuilder();
            Long enoughStorageId = null;
            whId:
            for (Long whId : storageStockMap.keySet()) {
                List<StockRecordPageDto> stockRecordPageDtos = storageStockMap.get(whId);
                Map<Long, StockRecordPageDto> productStockMap = stockRecordPageDtos.stream().collect(Collectors.toMap(StockRecordPageDto::getProductId, value -> value, (o1, o2) -> o1));
                for (OrderOutProductAddNewReq orderOutProductAddNewReq : productReqList.get(platformNo)) {
                    StockRecordPageDto stockRecord = productStockMap.get(orderOutProductAddNewReq.getProductId());
                    if (stockRecord == null || (stockRecord.getCanSellCount() - stockRecord.getNoDelivered() - stockRecord.getTurnFba() - orderOutProductAddNewReq.getCount()) < 0) {
                        continue whId;
                    }
                }
                enoughStorageId = whId;
                for (OrderOutProductAddNewReq orderOutProductAddNewReq : productReqList.get(platformNo)) {
                    StockRecordPageDto stockRecord = productStockMap.get(orderOutProductAddNewReq.getProductId());
                    stockRecord.setCanotSellCount(stockRecord.getCanotSellCount() - orderOutProductAddNewReq.getCount());
                    if (sku.length() > 0) {
                        sku.append(",");
                    }
                    sku.append(orderOutProductAddNewReq.getCommoditySku());
                    if (storageSku.length() > 0) {
                        storageSku.append(",");
                    }
                    storageSku.append(storageSkuMap.get(orderOutProductAddNewReq.getProductId()));
                    ProductInfoDo productBBInfoDo = productBBMap.get(orderOutProductAddNewReq.getProductId());
                    if (productBBInfoDo != null) {
                        if (productBBInfoDo.getBattery() == 1) {
                            dGoods = 2;
                        } else if (productBBInfoDo.getBreakable() == 1) {
                            dGoods = 1;
                        }
                    }
                }
                break whId;
            }
            if (enoughStorageId == null) {
                tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.Product_Stock_NotEnough_)));
                etList.remove(k);
                k--;
                continue order;
            }
            etList.get(k).setStorageId(enoughStorageId);
            etList.get(k).setCommoditySku(sku.toString());
            etList.get(k).setStorageSku(storageSku.toString());
            etList.get(k).setDangerousGood(dGoods);
            packageInsertDtos.add(new OrderOutPackageInsertDto(platformNo, 1, userid));
            productAddReqList.addAll(productReqList.get(platformNo));

            OperateRecordAddDto operateRecordAddDto = new OperateRecordAddDto(etList.get(k).getOrderNo(), "导入订单", null, null, 3, new Date(), userid);
            operateRecordDos.add(operateRecordAddDto);
        }
        if (!etList.isEmpty()) {
            //批量去插入
            dao.insertBatch(etList);
            //插入包裹 和 产品表
            etList.forEach(et -> packageInsertDtos.stream().filter(pack -> pack.getOrderNo().equals(et.getOrderNo())).forEach(pack -> pack.setOrderOutputId(et.getId())));
            List<OrderOutPackageInsertDto> tempPack = packageInsertDtos.stream().filter(pack -> pack.getOrderOutputId() != null).collect(Collectors.toList());
            packageDao.insertBatch(tempPack);
            etList.forEach(et -> productAddReqList.stream().filter(product -> Objects.equals(product.getOrderNo(), et.getOrderNo())).forEach(product -> product.setOrderId(et.getId())));
            tempPack.forEach(pack -> productAddReqList.stream().filter(product -> Objects.equals(product.getOrderNo(), pack.getOrderNo())).forEach(product -> product.setPackageId(pack.getId())));
            productDao.insertBatch(productAddReqList);
            etList.forEach(et -> operateRecordDos.stream().filter(operate -> Objects.equals(operate.getOrderNo(), et.getOrderNo())).forEach(operate -> operate.setThirdId(et.getId())));
            operateRecordDao.insertList(operateRecordDos.stream().filter(operate -> operate.getThirdId() != null).collect(Collectors.toList()));
        }
        return tips;
    }


    public SingleResult dealwithExcelNew(MultipartFile file, Long shopId, Integer storageId, Long userid, Long companyId) {
        //判断redis 10秒内有没有重复处理
        String redisKey = "OrderOut_uploadExcel_SendMsg" + shopId;
        Object o = redisTemplate.opsForValue().get(redisKey);
        if (o != null) {
//            throw new BizException(SysConstant.OrderOut_UploadExcel_ERROR);
        }
        if (shopId == null) throw new BizExceptionI18(SysConstant.Order_Send_NoShop);
        if (storageId == null || storageId == 0) throw new BizExceptionI18(SysConstant.Order_Send_NoStorage);
        sufficientFundsCheck(companyId);
        redisTemplate.opsForValue().set(redisKey, 1, 60 * 10, TimeUnit.SECONDS);
        if (StringUtils.isEmpty(file.getName())) {
            redisTemplate.delete(redisKey);
            throw new BizExceptionI18(SysConstant.File_Name_Null);
        }
        String originalFilename = file.getOriginalFilename();
        String suffix = file.getOriginalFilename().substring(originalFilename.lastIndexOf(".") + 1);
        if (!GlobalConstants.IMG_TYPE_XLS.equals(suffix.toUpperCase()) &&
                !GlobalConstants.IMG_TYPE_CSV.equals(suffix.toUpperCase())
                && !GlobalConstants.IMG_TYPE_XLSX.equals(suffix.toUpperCase())) {
            redisTemplate.delete(redisKey);
            throw new BizExceptionI18(SysConstant.File_Form_Incorrect);
        }
        InputStream soureFileInputStream = null;
        try {
            soureFileInputStream = file.getInputStream();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        Long fileId = null;
        //将文件保存到服务器
        try {
            //方案二 直接上传到正式路径
            fileId = fileService.uploadFileToFormalPath(soureFileInputStream, originalFilename);
            if (fileId != null && fileId != 0L) {
                fileService.addFileMoreDo(fileId, 0L, "orderOutputSend");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        String fileUrl = fileService.getFilePath(fileId);
        FileImportRecordDo recordDo = new FileImportRecordDo("output", fileId, null, companyId, shopId, 0, 0, new Date(), userid);
        recordDo.setSourceFileUrl(fileUrl);
        recordDo.setDeleteFlag(0);
        fileImportRecordDao.insert(recordDo);
        threadPoolTaskExecutor.execute(() -> {
            int orderCount = 0;
            List<OrderImportErrorVo1> tips = new ArrayList<>();
            List<OrderOutputExcelImport> excelImportList = null;
            List<OrderOutputExcelImportNew> excelNewImportList = null;
            List<OrderOutputDo> etList = new ArrayList<>();
            if (companyId.intValue() == 591) {
                try {
                    CsvImportParams params = new CsvImportParams();
                    params.setEncoding("Shift-JIS");
                    excelNewImportList = CsvImportUtil.importCsv(file.getInputStream(), OrderOutputExcelImportNew.class, params);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (excelNewImportList == null) {
                    redisTemplate.delete(redisKey);
                    throw new BizExceptionI18(SysConstant.File_FormWork_Incorrect);
                }
                Map<String, List<OrderOutputExcelImportNew>> collect = excelNewImportList.stream().filter(o1 -> StringUtils.isNotBlank(o1.getPlatformNo())).collect(Collectors.groupingBy(i -> stringTrim(i.getPlatformNo())));
                orderCount = collect.size();
                tips = this.dealExcelData(etList, collect, shopId, storageId, userid, companyId, "oms");
            }
            List<OrderImportErrorVo1> errorVo1List = new ArrayList<>(tips);
            Long errorFileId = null;
            if (!errorVo1List.isEmpty()) {
                String fileName = "错误原因—" + file.getOriginalFilename();
                Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), OrderImportErrorVo1.class, errorVo1List);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                InputStream inputStream = null;
                try {
                    workbook.write(bos);
                    bos.flush();
                    inputStream = new ByteArrayInputStream(bos.toByteArray());
                    bos.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                errorFileId = fileService.uploadFileToFormalPath(inputStream, fileName);
            }
            recordDo.setSuccessCount(orderCount - tips.size());
            recordDo.setErrorCount(tips.size());
            recordDo.setStatus(1);
            recordDo.setErrorFileId(errorFileId);
            if (errorFileId != null) {
                String errorFileUrl = fileService.getFilePath(errorFileId);
                recordDo.setErrorFileUrl(errorFileUrl);
            }
            recordDo.setStatus(1);
            fileImportRecordDao.updateById(recordDo);
            redisTemplate.delete(redisKey);
            this.dealExcelDataAfter(etList, userid);
        });
//        if (tips.size() > 0) {
//            return SingleResult.failure("300", SysConstant.IMPORT_OUT_ORDER_SUCCESS_ID, tips, orderCount - tips.size());
//        } else {
//            return SingleResult.success(SysConstant.IMPORT_OUT_ORDER_SUCCESS_ID, null, orderCount);
//        }
        return SingleResult.success("操作成功", "正在处理中,请稍候在 导入记录历史 中查看");
    }


    /**
     * Labella oms api 导入订单
     *
     * @param excelNewImportList
     * @return
     */
    @Override
    public List<OrderImportErrorVo1> dealForLabella(List<OrderOutputExcelImportNew> excelNewImportList) {
        Map<String, List<OrderOutputExcelImportNew>> collect = excelNewImportList.stream().filter(o1 -> StringUtils.isNotBlank(o1.getPlatformNo())).collect(Collectors.groupingBy(i -> stringTrim(i.getPlatformNo())));
        List<OrderOutputDo> etList = new ArrayList<>();
        List<OrderImportErrorVo1> errorVo1List = this.dealExcelData(etList, collect, 681L, 15, 1L, 591L, "omsApi");
        this.dealExcelDataAfter(etList, 1L);
        if (errorVo1List == null) {
            return new ArrayList<>();
        }
        return errorVo1List;
    }

    public List<OrderImportErrorVo1> dealExcelData(List<OrderOutputDo> etList, Map<String, List<OrderOutputExcelImportNew>> collect, Long shopId, Integer storageId, Long userid, Long companyId, String type) {
        List<OrderImportErrorVo1> tips = new ArrayList<>();
        //先校验基本格式
        List<String> platformNos = new ArrayList<>(collect.keySet());
        if (platformNos.isEmpty()) {
            return tips;
        }
        List<JpRegionDo> regionDoList = regionService.list();
        Map<String, JpRegionDo> areaMap = regionDoList.stream().collect(Collectors.toMap(JpRegionDo::getName, jpRegionDo -> jpRegionDo));
        //获取所有的产品
        Set<String> skuList = new HashSet<>();
        platformNos.forEach(platformNo -> collect.get(platformNo).forEach(orderOutputExcelImportNew -> skuList.add(orderOutputExcelImportNew.getCommoditySku().trim().replaceAll("\\n", "").trim().replaceAll(" ", ""))));
        Map<String, Long> skuMap = new HashMap<>();
        if (!skuList.isEmpty()) {
            Map<String, Long> skuMao = productInfoDao.getProductSkuAndIdList(new ArrayList<>(skuList), "commodity_sku", companyId)
                    .stream().collect(Collectors.toMap(ProductSkuAndIdDto::getSku, ProductSkuAndIdDto::getId, (v1, v2) -> v2));
            skuMap.putAll(skuMao);
            List<String> leftStorageSkuList = skuList.stream().filter(sku -> !skuMao.containsKey(sku)).collect(Collectors.toList());
            Map<String, Long> storageSkuMap;
            if (!leftStorageSkuList.isEmpty()) {
                storageSkuMap = productInfoDao.getProductSkuAndIdList(leftStorageSkuList, "storage_sku", companyId)
                        .stream().collect(Collectors.toMap(ProductSkuAndIdDto::getSku, ProductSkuAndIdDto::getId, (v1, v2) -> v2));
                skuMap.putAll(storageSkuMap);
            } else {
                storageSkuMap = new HashMap<>();
            }
            List<String> leftSubSkuMap = leftStorageSkuList.stream().filter(sku -> !storageSkuMap.containsKey(sku)).collect(Collectors.toList());
            if (!leftSubSkuMap.isEmpty()) {
                Map<String, Long> subSkuMap = productInfoDao.getSubProductSkuAndIdList(leftStorageSkuList, companyId).stream().collect(Collectors.toMap(ProductSkuAndIdDto::getSku, ProductSkuAndIdDto::getId, (v1, v2) -> v2));
                skuMap.putAll(subSkuMap);
            }
        }
        //获取所有的组合产品
        Map<Long, List<ProductCombinationDto>> combinationMap = productCombinationService.getCombinationList(companyId);
        LambdaQueryWrapper<OrderOutputDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(OrderOutputDo::getOrderNo, platformNos)
                .ne(OrderOutputDo::getStatus, DicBusinessItemConstant.outHasRecovered)
                .ne(OrderOutputDo::getStatus, DicBusinessItemConstant.orderCutOff)
                .eq(OrderOutputDo::getCompanyId, companyId)
                .select(OrderOutputDo::getOrderNo);
        List<Object> orderNos = baseMapper.selectObjs(wrapper);
        Map<String, List<OrderOutProductAddNewReq>> productReqList = new HashMap<>();

        Map<Long, String> productIdMap = new HashMap<>();
        if (!skuMap.isEmpty()) {
            productIdMap = productInfoService.list(new LambdaQueryWrapper<ProductInfoDo>().select(ProductInfoDo::getId, ProductInfoDo::getCommoditySku).in(ProductInfoDo::getId, skuMap.values()))
                    .stream().collect(Collectors.toMap(ProductInfoDo::getId, ProductInfoDo::getCommoditySku, (v1, v2) -> v2));
        }
        platformNo:
        for (int z = 0; z < platformNos.size(); z++) {
            String platformNo = platformNos.get(z);
            OrderOutputExcelImportNew excelData = collect.get(platformNo).get(0);
//                    OrderImportUtilVo importUtilVo = new OrderImportUtilVo(platformNo, excelData.getCommoditySku()
//                            , excelData.getPostCode(), excelData.getAddress(), excelData.getDeliveryDate(), companyId);
            if (orderNos.contains(platformNo)) {
                tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.ORDER_NUMBER_EXIST_No_id)));
                platformNos.remove(z);
                z--;
                continue;
            }
            if (StringUtils.isBlank(excelData.getCommoditySku())) {
                tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.Order_OrderNo_NoSkuMsg_new)));
                platformNos.remove(z);
                z--;
                continue;
            }
            if (StringUtils.isBlank(excelData.getPostCode())) {
                tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message("缺少邮编")));
                platformNos.remove(z);
                z--;
                continue;
            }
            if (StringUtils.isNotBlank(excelData.getReceiverName()) && excelData.getReceiverName().length() > 35) {
                tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.Order_Name_TooLong_Sim)));
                platformNos.remove(z);
                z--;
                continue;
            }

            if (StringUtils.isEmpty(excelData.getAddress())) {
                tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.Order_NoAddress, excelData.getPlatformNo())));
                platformNos.remove(z);
                z--;
                continue;
            }
            Date deliveryDate = null;
            if (StringUtils.isNotBlank(excelData.getDeliveryDate())) {
                String pattern = "yyyy/MM/dd";
                if (excelData.getDeliveryDate().contains("-")) {
                    pattern = "yyyy-MM-dd";
                }
                try {
                    deliveryDate = DateUtil.parse(excelData.getDeliveryDate(), pattern);
//                    deliveryDate = TimeUtils.parseDate(excelData.getDeliveryDate(), "yyyy/MM/dd");
                } catch (Exception e) {
                    e.printStackTrace();
                    tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.Order_ErrDateFormat, excelData.getPlatformNo())));
                    platformNos.remove(z);
                    z--;
                    continue;
                }
                //指定次日配达，把订单改成次日达订单
                // Date currentDate = TimeUtils.parseDate(TimeUtils.getCurrentDateFormat());//这个的格式 yyyy-MM-dd
                // int currentHour = Integer.parseInt(TimeUtils.getCurrentDateFormat("HH"));
                // if (currentHour < 12) {
                //     if (deliveryDate.getTime() - currentDate.getTime() <= 24 * 60 * 60 * 1000) {
                //         deliveryDate = DateUtil.offset(deliveryDate, DateField.DAY_OF_YEAR, 1);
                //     }
                // } else {
                //     if (deliveryDate.getTime() - currentDate.getTime() <= 48 * 60 * 60 * 1000) {
                //         deliveryDate = DateUtil.offset(deliveryDate, DateField.DAY_OF_YEAR, 1);
                //     }
                // }
                if (deliveryDate.getTime() - System.currentTimeMillis() > 1000 * 60 * 60 * 24 * 14) {
                    tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.MAX_DELIVERY_DAY_14)));
                    platformNos.remove(z);
                    z--;
                    continue;
                }
            }
            List<OrderOutProductAddNewReq> itemAddReqList = new ArrayList<>();
            for (OrderOutputExcelImportNew orderOutputExcelImportNew : collect.get(platformNo)) {
                Long productId = skuMap.get(orderOutputExcelImportNew.getCommoditySku());
                if (productId == null) {
                    tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.Product_NotExist_no_Index, orderOutputExcelImportNew.getCommoditySku())));
                    platformNos.remove(z);
                    z--;
                    continue platformNo;
                }
                if (!orderOutputExcelImportNew.getCount().matches("[0-9]+") || Integer.parseInt(orderOutputExcelImportNew.getCount()) < 1) {//todo
                    tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.Product_QuantityLess_no_Index, orderOutputExcelImportNew.getCommoditySku())));
                    platformNos.remove(z);
                    z--;
                    continue platformNo;
                }

                if (combinationMap.get(productId) != null) {
                    //说明是组合产品
                    for (ProductCombinationDto productCombinationDto : combinationMap.get(productId)) {
                        OrderOutProductAddNewReq productAddReq = new OrderOutProductAddNewReq();
                        productAddReq.setOrderNo(platformNo);
                        productAddReq.setProductId(productCombinationDto.getChildId());
                        productAddReq.setCommoditySku(productCombinationDto.getCommoditySku());
                        productAddReq.setCount(productCombinationDto.getCount() * Integer.parseInt(orderOutputExcelImportNew.getCount()));
                        productAddReq.setCreateBy(userid);
                        itemAddReqList.add(productAddReq);
                    }
                } else {
                    OrderOutProductAddNewReq productAddReq = new OrderOutProductAddNewReq();
                    productAddReq.setOrderNo(platformNo);
                    productAddReq.setProductId(productId);
                    productAddReq.setCommoditySku(productIdMap.get(productId));
                    productAddReq.setCount(Integer.parseInt(orderOutputExcelImportNew.getCount()));
                    productAddReq.setCreateBy(userid);
                    itemAddReqList.add(productAddReq);
                }
            }
            List<OrderOutProductAddNewReq> productAddReqfilter = new ArrayList<>(itemAddReqList.stream().collect(Collectors.toMap(OrderOutProductAddNewReq::getProductId, addReq1 -> addReq1, (o1, o2) -> {
                o1.setCount(o1.getCount() + o2.getCount());
                return o1;
            })).values());
            //验证库存
            if (productAddReqfilter.isEmpty()) {
                tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.Product_Info_NotNull)));
                platformNos.remove(z);
                z--;
                continue;
            }
            int orderType = productAddReqfilter.size() > 1 || productAddReqfilter.get(0).getCount() > 1 ? 2 : 1;
            OrderOutputDo et = new OrderOutputDo();
            et.setSendDate(new Date());
            et.setStatus(DicBusinessItemConstant.outCreateState);
            et.setShopId(shopId);
            et.setCompanyId(companyId);
            et.setStorageId((long) storageId);
            et.setOrderNo(platformNo);
            et.setCreateBy(userid);
//                    et.setCreateTime(new Date());
            et.setPostCode(stringTrim(excelData.getPostCode()));
            String regEx = "[^0-9||-||^０-９||－]";
            Pattern p = Pattern.compile(regEx);
            Matcher m = p.matcher(et.getPostCode());
            String post2 = m.replaceAll("").trim();
            et.setPostCode(post2);
            if (StringUtils.isNotBlank(excelData.getTelPhone())) {
                et.setTelPhone(stringTrim(excelData.getTelPhone()).replaceAll("\\+81", ""));
            }
            String area = stringTrim(excelData.getArea());
            et.setArea(area);
            JpRegionDo jpRegionDo = areaMap.get(area);
            if (jpRegionDo != null) {
                et.setAreaId(jpRegionDo.getId());
            } else {
                jpRegionDo = regionService.getRegionDoByPostCode(post2, regionDoList);
                if (jpRegionDo != null) {
                    et.setAreaId(jpRegionDo.getId());
                }
            }
            et.setAddress(stringTrim(excelData.getAddress()) + stringTrim(excelData.getAddress1()) + stringTrim(excelData.getAddress2()));
            et.setReceiverName(stringTrim(excelData.getReceiverName()) + stringTrim(excelData.getReceiverName2()));

            et.setDeliveryDate(deliveryDate);
            if (StringUtils.isNotBlank(excelData.getDeliveryTime())) {
                et.setDeliveryTime(excelData.getDeliveryTime().replaceAll(":00", "")
                        .replaceAll("时", "").replaceAll("時", ""));
            }
            if (excelData.getTrackName().equals("宅急便")) {
                et.setTrackId(DicBusinessItemConstant.yamatoExpress);
            } else if (excelData.getTrackName().equals("ネコポス")) {//ネコポス
                et.setTrackId(DicBusinessItemConstant.yamatoExpressSmall);
            }
            //一单一间
            et.setOrderType(orderType);
            et.setShipmentType(excelData.getShipmentType() == null ? 0 : excelData.getShipmentType());
            etList.add(et);
            productReqList.put(platformNo, productAddReqfilter);
        }
        //获取所有的仓库sku
        List<Long> productIds = new ArrayList<>();
        for (List<OrderOutProductAddNewReq> orderOutProductAddNewReqs : new ArrayList<>(productReqList.values())) {
            for (OrderOutProductAddNewReq orderOutProductAddNewReq : orderOutProductAddNewReqs) {
                if (productIds.contains(orderOutProductAddNewReq.getProductId())) {
                    continue;
                }
                productIds.add(orderOutProductAddNewReq.getProductId());
            }
        }
        Map<Long, String> storageSkuMap = new HashMap<>();
        Map<Long, ProductInfoDo> productBBMap = new HashMap<>();
        if (!productIds.isEmpty()) {
            storageSkuMap = productInfoDao.getFieldByProductIds(productIds, "storage_sku", companyId).stream().collect(Collectors.toMap(ProductSkuAndIdDto::getId, ProductSkuAndIdDto::getSku));
            LambdaQueryWrapper<ProductInfoDo> productQueryWrapper = new LambdaQueryWrapper<>();
            productQueryWrapper.select(ProductInfoDo::getId, ProductInfoDo::getCommoditySku, ProductInfoDo::getBattery, ProductInfoDo::getBreakable)
                    .in(ProductInfoDo::getId, productIds);
            productBBMap = productInfoDao.selectList(productQueryWrapper).stream().collect(Collectors.toMap(ProductInfoDo::getId, p -> p));
        }
        List<OrderOutPackageInsertDto> packageInsertDtos = new ArrayList<>();
        List<OrderOutProductAddNewReq> productAddReqList = new ArrayList<>();
        List<OperateRecordAddDto> operateRecordDos = new ArrayList<>();
        //再去验证库存
        Map<String, String> map = new HashMap<>();
        map.put("productIds", StringUtils.join(productIds, ","));
        map.put("shopId", String.valueOf(shopId));
        map.put("inStock", "2");
        map.put("storageId", String.valueOf(storageId));

        //目前 此方法 不支持店铺调货 以及自动选择仓库
        Map<Long, StockRecordPageDto> pageDtoMap = mStockRecordDao.listPage(map).stream().collect(Collectors.toMap(StockRecordPageDto::getProductId, stockRecordPageDto -> stockRecordPageDto, (v1, v2) -> v2));
        order:
        for (int k = 0; k < etList.size(); k++) {
            int dGoods = 0;
            String platformNo = etList.get(k).getOrderNo();
            StringBuilder sku = new StringBuilder();
            StringBuilder storageSku = new StringBuilder();
            for (OrderOutProductAddNewReq orderOutProductAddNewReq : productReqList.get(platformNo)) {
                StockRecordPageDto stockRecord = pageDtoMap.get(orderOutProductAddNewReq.getProductId());
                if (stockRecord == null || (stockRecord.getCanSellCount() - stockRecord.getNoDelivered() - stockRecord.getTurnFba() - orderOutProductAddNewReq.getCount()) < 0) {
                    tips.add(new OrderImportErrorVo1(platformNo, StringsUtil.createI18Message(SysConstant.Product_Stock_NotEnough, orderOutProductAddNewReq.getCommoditySku())));
                    etList.remove(k);
                    k--;
                    continue order;
                }
                stockRecord.setCanotSellCount(stockRecord.getCanotSellCount() - orderOutProductAddNewReq.getCount());
                if (sku.length() > 0) {
                    sku.append(",");
                }
                sku.append(orderOutProductAddNewReq.getCommoditySku());
                if (storageSku.length() > 0) {
                    storageSku.append(",");
                }
                storageSku.append(storageSkuMap.get(orderOutProductAddNewReq.getProductId()));
                ProductInfoDo productBBInfoDo = productBBMap.get(orderOutProductAddNewReq.getProductId());
                if (productBBInfoDo != null) {
                    if (productBBInfoDo.getBattery() == 1) {
                        dGoods = 2;
                    } else if (productBBInfoDo.getBreakable() == 1) {
                        dGoods = 1;
                    }
                }
            }
            etList.get(k).setCommoditySku(sku.toString());
            etList.get(k).setStorageSku(storageSku.toString());
            etList.get(k).setDangerousGood(dGoods);
            packageInsertDtos.add(new OrderOutPackageInsertDto(platformNo, 1, userid));
            productAddReqList.addAll(productReqList.get(platformNo));

            OperateRecordAddDto operateRecordAddDto = new OperateRecordAddDto(etList.get(k).getOrderNo(), "oms".equals(type) ? "导入订单" : "omsApi推单", null, null, 3, new Date(), userid);
            operateRecordDos.add(operateRecordAddDto);
        }
        if (!etList.isEmpty()) {
            //批量去插入
            dao.insertBatch(etList);
            //插入包裹 和 产品表
            etList.forEach(et -> packageInsertDtos.stream().filter(pack -> pack.getOrderNo().equals(et.getOrderNo())).forEach(pack -> pack.setOrderOutputId(et.getId())));
            List<OrderOutPackageInsertDto> tempPack = packageInsertDtos.stream().filter(pack -> pack.getOrderOutputId() != null).collect(Collectors.toList());
            packageDao.insertBatch(tempPack);
            etList.forEach(et -> productAddReqList.stream().filter(product -> Objects.equals(product.getOrderNo(), et.getOrderNo())).forEach(product -> product.setOrderId(et.getId())));
            tempPack.forEach(pack -> productAddReqList.stream().filter(product -> Objects.equals(product.getOrderNo(), pack.getOrderNo())).forEach(product -> product.setPackageId(pack.getId())));
            productDao.insertBatch(productAddReqList);
            etList.forEach(et -> operateRecordDos.stream().filter(operate -> Objects.equals(operate.getOrderNo(), et.getOrderNo())).forEach(operate -> operate.setThirdId(et.getId())));
            operateRecordDao.insertList(operateRecordDos.stream().filter(operate -> operate.getThirdId() != null).collect(Collectors.toList()));
        }
        return tips;
    }

    public void dealExcelDataAfter(List<OrderOutputDo> etList, Long userid) {
        if (!etList.isEmpty()) {
            threadPoolTaskExecutor.execute(() -> {
                Map<Long, StorageDo> storageMap = storageService.getStorageMap();
                //获取所有 的包裹信息
                Map<Long, List<OrderOutputProductDo>> productDoList = new HashMap<>();
                Map<Long, List<OrderOutputPackageDo>> packageDoList = new HashMap<>();
                List<Long> ids = etList.stream().map(OrderOutputDo::getId).collect(Collectors.toList());
                if (!ids.isEmpty()) {
                    productDoList = productDao.selectList(new LambdaQueryWrapper<OrderOutputProductDo>().in(OrderOutputProductDo::getOrderId, ids))
                            .stream().collect(Collectors.groupingBy(OrderOutputProductDo::getOrderId));
                    QueryWrapper<OrderOutputPackageDo> orderPackWrapper = new QueryWrapper<>();
                    orderPackWrapper.in("order_output_id", ids);
                    packageDoList = packageDao.selectList(new LambdaQueryWrapper<OrderOutputPackageDo>().in(OrderOutputPackageDo::getOrderOutputId, ids))
                            .stream().collect(Collectors.groupingBy(OrderOutputPackageDo::getOrderOutputId));
                }
                List<Long> orderProductIds = new ArrayList<>();
                productDoList.values().forEach(list -> orderProductIds.addAll(list.stream().map(OrderOutputProductDo::getProductId).collect(Collectors.toList())));
                Map<Long, ProductInfoDo> productmMap = new HashMap<>();
                if (!orderProductIds.isEmpty()) {
                    List<ProductInfoDo> productBeans = productInfoDao.selectList(new LambdaQueryWrapper<ProductInfoDo>()
                            .in(ProductInfoDo::getId, orderProductIds.stream().distinct().collect(Collectors.toList())));
                    productmMap = productBeans.stream().collect(Collectors.toMap(ProductInfoDo::getId, i -> i, (v1, v2) -> v1));
                }
                List<OrderOutputPackageDetailDo> packageDetailDoList = new ArrayList<>();
                for (OrderOutputDo outputDo : etList) {
                    String value = updateTrackId(outputDo, productDoList.get(outputDo.getId()), packageDoList.get(outputDo.getId()), productmMap, storageMap.get(outputDo.getStorageId()));
                    if (value != null) {
//                            throw new BizExceptionI18(SysConstant.Order_Create_Fair_Manual, outputDo.getOrderNo());
                    }
                    if (value == null) {
                        List<OrderOutputPackageDetailDo> oneOrderDetailList = dealwithPrintLabelPackageInfo(packageDoList.get(outputDo.getId()), productDoList.get(outputDo.getId()), outputDo, storageMap.get(outputDo.getStorageId()), userid, false);
                        packageDetailDoList.addAll(oneOrderDetailList);
                    }
                }
                if (!packageDetailDoList.isEmpty()) {
                    packageDetailDao.insertBatch(packageDetailDoList);
                }
            });
        }
    }


    /**
     * labella获取代理仓单号
     *
     * @return
     */
    @Override
    public List<LabellaOrderTrackNumberDto> labellaGetTrackNumber(List<String> platformOrderNos) {
        if (platformOrderNos == null || platformOrderNos.isEmpty()) {
            return new ArrayList<>();
        }
        List<LabellaOrderTrackNumberDto> trackNumberList = dao.getLabellaOrderTrackNumber(platformOrderNos);
        return trackNumberList.stream().filter(trackNumber -> StringUtils.isNotBlank(trackNumber.getTrackNumber())).collect(Collectors.toList());
    }


    @Override
    public void exportExcel(Map<String, String> map, OrderOutputExcelReq req, HttpServletResponse response) throws
            IOException {
        List<OrderOutputDo> orderOutputDoList = null;
        if (CollectionUtils.isEmpty(req.getIds())) {
            QueryWrapper<OrderOutputDo> wrapper = queryBuild(map, "list");
            orderOutputDoList = this.baseMapper.selectList(wrapper);
        } else {
            LambdaQueryWrapper<OrderOutputDo> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(OrderOutputDo::getId, req.getIds()).eq(OrderOutputDo::getCompanyId, map.get("companyId")).orderByDesc(OrderOutputDo::getId);
            orderOutputDoList = this.baseMapper.selectList(wrapper);
        }

        if (orderOutputDoList.size() > 10000) {
            throw new BizExceptionI18(SysConstant.File_Export_ToMuch10000);
        }
        List<OrderOutputExcelExportVo> excelExportVoList = new ArrayList<>();

        if (!CollectionUtils.isEmpty(orderOutputDoList)) {
            for (OrderOutputDo orderOutputDo : orderOutputDoList) {
                OrderOutputExcelExportVo excelExportVo = new OrderOutputExcelExportVo();

                BeanUtils.copyProperties(orderOutputDo, excelExportVo);

                DicBusinessItemDo businessItemDo = dicBusinessItemDao.selectById(orderOutputDo.getStatus());
                if (businessItemDo != null) {
                    excelExportVo.setStatus(businessItemDo.getDicItemValue());
                }
                ShopDo shopDo = shopDao.selectById(orderOutputDo.getShopId());
                if (shopDo != null) {
                    excelExportVo.setShopName(shopDo.getShopName());
                }
                StorageDo storageDo = storageDao.selectById(orderOutputDo.getStorageId());
                if (storageDo != null) {
                    excelExportVo.setStorageName(storageDo.getStorageName());
                }
                DicBusinessItemDo dic = dicBusinessItemDao.selectById(orderOutputDo.getTrackId());
                if (dic != null) {
                    excelExportVo.setTrackName(StaticDict.Track_Type.getText(dic.getParentId()));
                }
                excelExportVo.setArea(StringsUtil.getJpAreaByEnglishCode(orderOutputDo.getArea() == null ? "" : orderOutputDo.getArea()));

                int count = productDao.selectCountByOrderId(orderOutputDo.getId());
                excelExportVo.setSkuCount(count);
                LambdaQueryWrapper<OrderOutputPackageDetailDo> packageDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                packageDoLambdaQueryWrapper.eq(OrderOutputPackageDetailDo::getOrderOutputId, orderOutputDo.getId());
                List<OrderOutputPackageDetailDo> packageDoList = packageDetailDao.selectList(packageDoLambdaQueryWrapper);

                List<OrderOutputPackageExcelExportVo> packageExcelExportVoList = new ArrayList<>();
                for (OrderOutputPackageDetailDo packageDo : packageDoList) {
                    OrderOutputPackageExcelExportVo packageExcelExportVo = new OrderOutputPackageExcelExportVo();
                    BeanUtils.copyProperties(packageDo, packageExcelExportVo);
                    if (!DicBusinessItemConstant.yamatoExpressBox.equals(orderOutputDo.getTrackId()) && packageDo.getMaterialId() != null && packageDo.getMaterialId() != -1L) {
                        ProductInfoDo productInfoDo = productInfoDao.selectObject(packageDo.getMaterialId());
                        packageExcelExportVo.setMaterialSku(productInfoDo.getCommoditySku());
                        packageExcelExportVo.setLength(packageDo.getMLength());
                        packageExcelExportVo.setWidth(packageDo.getMWidth());
                        packageExcelExportVo.setHeight(packageDo.getMHeight());
                    } else {
                        packageExcelExportVo.setMaterialSku(packageDo.getMaterialId() == null ? "无需耗材" : "无合适耗材");
                    }
                    if (StringUtils.isNotBlank(packageDo.getInSkuId())) {
                        List<OrderOutputProductExcelExportVo> productExcelExportVoList = new ArrayList<>();
                        String[] split = packageDo.getInSkuId().split(",");
                        Map<String, Long> stringLongMap = Arrays.stream(split).collect(Collectors.groupingBy(s -> s, Collectors.counting()));
                        for (String productId : stringLongMap.keySet()) {
                            if (StringUtils.isBlank(productId)) {
                                continue;
                            }
                            OrderOutputProductExcelExportVo productExportVo = new OrderOutputProductExcelExportVo();
                            ProductInfoDo productInfoDo = productInfoDao.selectObject(Long.parseLong(productId));
                            if (productInfoDo != null) {
                                productExportVo.setCount(stringLongMap.get(productId).intValue());
                                productExportVo.setCommoditySku(productInfoDo.getCommoditySku());
                                productExportVo.setStorageSku(productInfoDo.getStorageSku());
                                if (StringUtils.isNotBlank(productInfoDo.getCommodityName())) {
                                    productExportVo.setProductName(productInfoDo.getCommodityName());
                                } else {
                                    productExportVo.setProductName(productInfoDo.getProductName());
                                }
                                productExcelExportVoList.add(productExportVo);
                            }
                        }
                        packageExcelExportVo.setProductExcelExportVoList(productExcelExportVoList);
                    }

                    packageExcelExportVoList.add(packageExcelExportVo);
                    excelExportVo.setPackageExcelExportVoList(packageExcelExportVoList);
                }

                excelExportVoList.add(excelExportVo);
            }
        }
        CompanyDo companyDo = companyDao.selectById(map.get("companyId"));
        ExcelUtils.exportExcel(excelExportVoList, OrderOutputExcelExportVo.class, "出库订单" + "-" + companyDo.getCompanyCode(), new ExportParams(), response);
    }

    @Override
    public List<String> addRakutenList(List<OrderOutputAddReq> orderOutputAddReqList, Long currentUserId) {
        List<String> failedOrderids = new ArrayList<>();
        for (OrderOutputAddReq outputAddReq : orderOutputAddReqList) {
            String value = add(outputAddReq, currentUserId);
            if (value != null) {
                failedOrderids.add(value);
                operateRecordDao.operateAddRecordAndValue(SysConstant.OPERATE_CLICK_SEND_ERROR, value, Long.parseLong(outputAddReq.getPlatformNumber()), currentUserId, 5);
            } else {
                operateRecordDao.operateAddRecord(SysConstant.OPERATE_CLICK_SEND, Long.parseLong(outputAddReq.getPlatformNumber()), currentUserId, 5);
                rakutenDao.updateOrderSendOut(outputAddReq.getPlatformNumber());
            }
        }
        return failedOrderids;
    }

    @Override
    public List<String> addQoo10List(List<OrderOutputAddReq> orderOutputAddReqList, Long currentUserId) {
        List<String> failedOrderids = new ArrayList<>();
        for (OrderOutputAddReq outputAddReq : orderOutputAddReqList) {
            String value = add(outputAddReq, currentUserId);
            if (value != null) {
                failedOrderids.add(value);
            } else {
                if (StringUtils.isNotBlank(outputAddReq.getOrderNo())) {
                    qoo10Dao.updateOrderSendOut(outputAddReq.getOrderNo());
                }
            }
        }
        return failedOrderids;
    }

    @Override
    public List<String> addAmazonVDFList(Iterable<OrderOutputAddReq> orderOutputAddReqList, Long userId) {
        List<String> failedOrderids = new ArrayList<>();
        for (OrderOutputAddReq outputAddReq : orderOutputAddReqList) {
            String value = add(outputAddReq, userId);
            if (value != null) {
                failedOrderids.add(value);
                operateRecordDao.operateAddRecordAndValue(SysConstant.OPERATE_CLICK_SEND_ERROR, value, Long.parseLong(outputAddReq.getPlatformNumber()), userId, 10);
            } else {
                operateRecordDao.operateAddRecord(SysConstant.OPERATE_CLICK_SEND, Long.parseLong(outputAddReq.getPlatformNumber()), userId, 10);
                vdfService.updateOrderSendOut(outputAddReq.getPlatformNumber());
            }
        }
        return failedOrderids;
    }

    @Override
    public List<String> addAmazonList(Iterable<OrderOutputAddReq> orderOutputAddReqList, Long userId) {
        List<String> failedOrderids = new ArrayList<>();
        for (OrderOutputAddReq outputAddReq : orderOutputAddReqList) {
            String value = add(outputAddReq, userId);
            if (value != null) {
                failedOrderids.add(value);
                operateRecordDao.operateAddRecordAndValue(SysConstant.OPERATE_CLICK_SEND_ERROR, value, Long.parseLong(outputAddReq.getPlatformNumber()), userId, 4);
            } else {
                operateRecordDao.operateAddRecord(SysConstant.OPERATE_CLICK_SEND, Long.parseLong(outputAddReq.getPlatformNumber()), userId, 4);

                amazonDao.updateOrderSendOut(outputAddReq.getPlatformNumber());
            }
        }
        return failedOrderids;
    }

    @Override
    public List<String> addYahooList(Iterable<OrderOutputAddReq> orderOutputAddReqList, Long userId) {
        List<String> failedOrderids = new ArrayList<>();
        for (OrderOutputAddReq outputAddReq : orderOutputAddReqList) {
            String value = add(outputAddReq, userId);
            if (value != null) {
                failedOrderids.add(value);
                operateRecordDao.operateAddRecordAndValue(SysConstant.OPERATE_CLICK_SEND_ERROR, value, Long.parseLong(outputAddReq.getPlatformNumber()), userId, 11);
            } else {
                operateRecordDao.operateAddRecord(SysConstant.OPERATE_CLICK_SEND, Long.parseLong(outputAddReq.getPlatformNumber()), userId, 11);
                yahooDao.updateOrderSendOut(outputAddReq.getPlatformNumber());
            }
        }
        return failedOrderids;
    }


    @Override
    public List<String> addShopifyList(Iterable<OrderOutputAddReq> orderOutputAddReqList, Long userId) {
        List<String> failedOrderids = new ArrayList<>();
        for (OrderOutputAddReq outputAddReq : orderOutputAddReqList) {
            String value = add(outputAddReq, userId);
            if (value != null) {
                failedOrderids.add(value);
                operateRecordDao.operateAddRecordAndValue(SysConstant.OPERATE_CLICK_SEND_ERROR, value, Long.parseLong(outputAddReq.getPlatformNumber()), userId, 7);
            } else {
                operateRecordDao.operateAddRecord(SysConstant.OPERATE_CLICK_SEND, Long.parseLong(outputAddReq.getPlatformNumber()), userId, 7);
                shopifyDao.updateOrderSendOut(outputAddReq.getPlatformNumber());
            }
        }
        return failedOrderids;
    }

    private String dealwithExcelData(int index, List<OrderOutputExcelImportNew> excelDataList, Long shopId, Integer storageId, Long userid) {
        OrderOutputExcelImportNew excelData = excelDataList.get(0);
        ShopDo shopDo = shopDao.selectById(shopId);
        if (shopDo == null) return StringsUtil.createI18Message(SysConstant.Shop_NotExist_Index);
        String value = checkOrderNo(excelData.getPlatformNo(), shopDo.getCompanyId());
        String stringIndex = String.format("Line%d: ", index);
        if (value != null) {
            return StringsUtil.createI18Message(SysConstant.Order_OrderNo_Exist, excelData.getPlatformNo());
        }
        OrderOutputDo outputDo = new OrderOutputDo();
        outputDo.setSendDate(new Date());
        outputDo.setStatus(DicBusinessItemConstant.outCreateState);
        if (StringUtils.isEmpty(excelData.getCommoditySku()))
            return StringsUtil.createI18Message(SysConstant.Order_OrderNo_NoSkuMsg, excelData.getPlatformNo());
        outputDo.setShopId(shopId);
        outputDo.setCompanyId(shopDo.getCompanyId());
        outputDo.setStorageId((long) storageId);
//        outputDo.setOrderType(1);
        String regEx = "[^0-9||-||^０-９||－]";
        Pattern p = Pattern.compile(regEx);
        outputDo.setOrderNo(stringTrim(excelData.getPlatformNo()));
        outputDo.setCreateBy(userid);
        outputDo.setCreateTime(new Date());
        if (StringUtils.isEmpty(excelData.getPostCode()))
            return StringsUtil.createI18Message(SysConstant.Order_NoZipCode, excelData.getPlatformNo());
        outputDo.setPostCode(stringTrim(excelData.getPostCode()));
        Matcher m = p.matcher(outputDo.getPostCode());
        String post2 = m.replaceAll("").trim();
        outputDo.setPostCode(post2);
        if (StringUtils.isNotBlank(excelData.getTelPhone())) {
            outputDo.setTelPhone(stringTrim(excelData.getTelPhone()).replaceAll("\\+81", ""));
            // Matcher m1 = p.matcher(outputDo.getTelPhone());
            // String post1 = m1.replaceAll("").replaceAll("\\+81", "").trim();
            // outputDo.setTelPhone(post1.trim());
        }

        if (StringUtils.isNotBlank(excelData.getArea()))
            outputDo.setArea(stringTrim(excelData.getArea()));
        outputDo.setCreateTime(new Date());
        if (StringUtils.isEmpty(excelData.getAddress()))
            return StringsUtil.createI18Message(SysConstant.Order_NoAddress, excelData.getPlatformNo());
        outputDo.setAddress(stringTrim(excelData.getAddress()) + stringTrim(excelData.getAddress1()) + stringTrim(excelData.getAddress2()));
        if (StringUtils.isNotBlank(excelData.getReceiverName()))
            outputDo.setReceiverName(stringTrim(excelData.getReceiverName()) + stringTrim(excelData.getReceiverName2()));
//        if (excelData.getDeliveryDate()!=null)
//            outputDo.setDeliveryDate(excelData.getDeliveryDate());
        if (StringUtils.isNotBlank(excelData.getDeliveryDate())) {
            try {
                Date deliveryDate = TimeUtils.parseDate(excelData.getDeliveryDate(), "yyyy/MM/dd");
                //指定次日配达，把订单改成次日达订单
                Date currentDate = TimeUtils.parseDate(TimeUtils.getCurrentDateFormat());//这个的格式 yyyy-MM-dd
                int currentHour = Integer.parseInt(TimeUtils.getCurrentDateFormat("HH"));
                if (currentHour < 12) {
                    if (deliveryDate.getTime() - currentDate.getTime() <= 24 * 60 * 60 * 1000) {
                        excelData.setDeliveryDate(DateUtil.format(DateUtil.offset(deliveryDate, DateField.DAY_OF_YEAR, 1), "yyyy/MM/dd"));
                        // excelData.setShipmentType(SHIPMENT_TYPE_1);
                    }
                } else {
                    if (deliveryDate.getTime() - currentDate.getTime() <= 48 * 60 * 60 * 1000) {
                        excelData.setDeliveryDate(DateUtil.format(DateUtil.offset(deliveryDate, DateField.DAY_OF_YEAR, 2), "yyyy/MM/dd"));
                        // excelData.setShipmentType(SHIPMENT_TYPE_1);
                    }
                }
                DateTime date = DateUtil.parse(excelData.getDeliveryDate(), "yyyy/MM/dd");
                if (date.getTime() - System.currentTimeMillis() > 1000 * 60 * 60 * 24 * 14) {
                    return StringsUtil.createI18Message(SysConstant.MAX_DELIVERY_DAY_14);
                }
//                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
//                Date date = dateFormat.parse(excelData.getDeliveryDate());
                outputDo.setDeliveryDate(date);
            } catch (Exception e) {
                e.printStackTrace();
                return StringsUtil.createI18Message(SysConstant.Order_ErrDateFormat, excelData.getPlatformNo());
            }
        }
        if (StringUtils.isNotBlank(excelData.getDeliveryTime())) {
            outputDo.setDeliveryTime(excelData.getDeliveryTime().replaceAll(":00", "")
                    .replaceAll("时", "").replaceAll("時", ""));
        }
        if (excelData.getTrackName().equals("宅急便")) {
            outputDo.setTrackId(DicBusinessItemConstant.yamatoExpress);
        } else if (excelData.getTrackName().equals("ネコポス")) {//ネコポス
            outputDo.setTrackId(DicBusinessItemConstant.yamatoExpressSmall);
        }
        // if (SHIPMENT_TYPE_1.equals(excelData.getShipmentType())) {
        //     outputDo.setShipmentType(1);
        // } else if (SHIPMENT_TYPE_2.equals(excelData.getShipmentType())) {
        //     outputDo.setShipmentType(0);
        //     outputDo.setTrackId(StaticDict.Track_Type.YamatoExpressJCB.getValue());
        // } else {
        //     outputDo.setShipmentType(0);
        // }

        save(outputDo);
        List<OrderOutputProductAddReq> orderOutputExcelSkuList = excelDataList.stream().map(orderOutputExcelImportNew -> {
            OrderOutputProductAddReq skuVo = new OrderOutputProductAddReq(Integer.parseInt(orderOutputExcelImportNew.getCount()), orderOutputExcelImportNew.getCommoditySku());
            return skuVo;
        }).collect(Collectors.toList());
        try {
            dealwithExcelProductNew(stringIndex, outputDo, orderOutputExcelSkuList, shopDo.getCompanyId());
        } catch (BizException e) {
            e.printStackTrace();
            dao.deleteById(outputDo.getId());
            return StringsUtil.createI18Message(e.getErrorMsg(), e.getArgs());
        }
        return outputDo.getId() + "";
    }

    private void dealwithExcelProductNew(String stringIndex, OrderOutputDo outputDo, List<OrderOutputProductAddReq> productAddReqList, Long companyId) {
        OrderOutputPackageDo packageDo = new OrderOutputPackageDo();
        packageDo.setOrderOutputId(outputDo.getId());
        packageDo.setCreateBy(outputDo.getCreateBy());
        packageDo.setCreateTime(new Date());
        packageDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
        packageDao.insert(packageDo);
        StringBuilder stringBuilder = new StringBuilder();
        StringBuilder stringBuilder2 = new StringBuilder();

        if (outputDo.getStorageId() != 0) {
            List<OrderOutputProductAddReq> productInfoDoList = new ArrayList<>();
            for (OrderOutputProductAddReq orderOutputProductAddReq : productAddReqList) {
                productInfoDoList.addAll(dealwithExcelProductAndStock(outputDo, packageDo.getId(), stringIndex,
                        orderOutputProductAddReq.getCount(), orderOutputProductAddReq.getCommoditySku(), companyId));
            }
            // //todo 产品数量过多时需要人工审核，状态改为-1
            // if (StringUtils.isNotBlank(excelData.getCommoditySku1())) {
            //
            //     // for (OrderOutputProductAddReq orderOutputProductAddReq : productInfoDoList) {
            //     //     if (stringBuilder.length() > 0) stringBuilder.append(",");
            //     //     stringBuilder.append(orderOutputProductAddReq.getCommoditySku());
            //     //     if (stringBuilder2.length() > 0) stringBuilder.append(",");
            //     //     stringBuilder2.append(orderOutputProductAddReq.getStorageSku());
            //     // }
            // } else {
            //     throw new BizExceptionI18(SysConstant.Product_NotExist_Index, stringIndex, excelData.getCommoditySku1());
            // }
            // //产品2
            // if (StringUtils.isNotBlank(excelData.getCommoditySku2())) {
            //     productInfoDoList.addAll(dealwithExcelProductAndStock(outputDo, packageDo.getId(), stringIndex,
            //             excelData.getCount2(), excelData.getCommoditySku2(), companyId));
            // }
            // //产品3
            // if (StringUtils.isNotBlank(excelData.getCommoditySku3())) {
            //     productInfoDoList.addAll(dealwithExcelProductAndStock(outputDo, packageDo.getId(), stringIndex,
            //             excelData.getCount3(), excelData.getCommoditySku3(), companyId));
            // }
            // //产品4
            // if (StringUtils.isNotBlank(excelData.getCommoditySku4())) {
            //     productInfoDoList.addAll(dealwithExcelProductAndStock(outputDo, packageDo.getId(), stringIndex,
            //             excelData.getCount4(), excelData.getCommoditySku4(), companyId));
            // }

            List<OrderOutputProductAddReq> productAddReqfilter = new ArrayList<>(productInfoDoList.stream().collect(Collectors.toMap(OrderOutputProductAddReq::getProductId, addReq1 -> addReq1, (o1, o2) -> {
                o1.setCount(o1.getCount() + o2.getCount());
                return o1;
            })).values());
            for (OrderOutputProductAddReq orderOutputProductAddReq : productAddReqfilter) {
                if (stringBuilder.length() > 0) stringBuilder.append(",");
                stringBuilder.append(orderOutputProductAddReq.getCommoditySku());
                if (stringBuilder2.length() > 0) stringBuilder.append(",");
                stringBuilder2.append(orderOutputProductAddReq.getStorageSku());
                OrderOutputProductDo outputProductDo1 = new OrderOutputProductDo();
                outputProductDo1.setProductId(orderOutputProductAddReq.getProductId());
                outputProductDo1.setCount(orderOutputProductAddReq.getCount());
                outputProductDo1.setOrderId(outputDo.getId());
                outputProductDo1.setPackageId(packageDo.getId());
                outputProductDo1.setCreateBy(outputDo.getCreateBy());
                outputProductDo1.setCreateTime(new Date());
                outputProductDo1.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
                verifyStock(outputDo.getCompanyId(), outputDo.getShopId(), outputDo.getStorageId(),
                        outputProductDo1.getProductId(), outputProductDo1.getCount(), orderOutputProductAddReq.getCommoditySku());
                productDao.insert(outputProductDo1);
            }
        } else {//不指定仓库，系统自动选择
            long storageId = 0L;
            //自动分配仓库
            Long stateId = regionService.getStateIdByPostCode(outputDo.getPostCode());
            // if (stateId <= 7 || (stateId != 9 && companyId == 32)) {//大阪地区优先发货仓库
            //     storageId = 12L;
            // } else if (stateId >= 8) {//东京仓库优先发货仓库
            storageId = 15L;
            // }
            long lastStorageId = storageId;
            List<OrderOutputProductAddReq> productAddReqUploadList = new ArrayList<>();

            for (OrderOutputProductAddReq productDo : productAddReqList) {//多个产品判断
                Long productId = getProductId(productDo.getCommoditySku(), outputDo.getCompanyId());
                ProductInfoDo productInfoDo = productInfoDao.selectById(productId);
                if (productId == null)
                    throw new BizExceptionI18(SysConstant.Order_SkuNotfound, outputDo.getOrderNo(), productDo.getCommoditySku());
                try {
                    verifyStock(outputDo.getCompanyId(), outputDo.getShopId(), storageId, productId, productDo.getCount(), productDo.getCommoditySku());
                    OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                    productDetail.setProductId(productId);
                    productDetail.setCount(productDo.getCount());
                    if (stringBuilder.length() > 0) stringBuilder.append(",");
                    stringBuilder.append(productDo.getCommoditySku());
                    if (stringBuilder2.length() > 0) stringBuilder2.append(",");
                    stringBuilder2.append(productInfoDo.getStorageSku());
                    productAddReqUploadList.add(productDetail);
                } catch (Exception e) {
                    e.printStackTrace();
                    storageId = 0;
                }

            }
            outputDo.setStorageId(storageId);
            //一个仓库是否发完所有订单
            if (storageId == 0) {
                List<OrderRakutenProductDo> productDoListFailed = new ArrayList<>();
                LambdaQueryWrapper<StorageDo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(StorageDo::getSupportShip, 1).ne(StorageDo::getId, lastStorageId);
                if (stateId <= 7 || (stateId != 9 && companyId == 32)) {
                    lambdaQueryWrapper.orderByDesc(StorageDo::getStorageArea);
                } else {
                    lambdaQueryWrapper.orderByAsc(StorageDo::getStorageArea);
                }
                List<StorageDo> storageDos = storageDao.selectList(lambdaQueryWrapper);
                storageId = 0L;
                if (storageDos != null) {
                    kk:
                    for (StorageDo storageDo : storageDos) {
                        //遍历支持捆包仓库是否都有库存
                        for (OrderOutputProductAddReq productDo : productAddReqList) {//多个产品判断
                            Long productId = getProductId(productDo.getCommoditySku(), outputDo.getCompanyId());
                            ProductInfoDo productInfoDo = productInfoDao.selectById(productId);
                            if (productId == null)
                                throw new BizException(SysConstant.Order_SkuNotfound, outputDo.getOrderNo(), productDo.getCommoditySku());
                            try {
                                verifyStock(outputDo.getCompanyId(), outputDo.getShopId(), storageDo.getId(), productId, productDo.getCount(), productDo.getCommoditySku());
                                OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                                productDetail.setProductId(productId);
                                productDetail.setCount(productDo.getCount());
                                if (stringBuilder.length() > 0) stringBuilder.append(",");
                                stringBuilder.append(productInfoDo.getCommoditySku());
                                if (stringBuilder2.length() > 0) stringBuilder2.append(",");
                                stringBuilder2.append(productInfoDo.getStorageSku());
                                productAddReqUploadList.add(productDetail);
                            } catch (Exception e) {
                                e.printStackTrace();
                                storageId = 0;
                                productAddReqUploadList.clear();
                                continue kk;
                            }

                        }
                        storageId = storageDo.getId();
                        break kk;
                    }
                    outputDo.setStorageId(storageId);
                }
                if (storageId == 0) {//捆包仓库无库存，分别发
                    LambdaQueryWrapper<StorageDo> queryWrapper = new LambdaQueryWrapper<>();
                    List<OrderOutputProductAddReq> productAddReqUploadList1 = new ArrayList<>();
                    queryWrapper.eq(StorageDo::getCountryType, 1);
                    List<StorageDo> storageDoList = storageDao.selectList(queryWrapper);
                    StringBuilder stringBuilderNoStock = new StringBuilder();
                    for (OrderOutputProductAddReq productDo : productAddReqList) {
                        storageId = 0L;
                        double shipPirce = 99999D;
                        Long productId = getProductId(productDo.getCommoditySku(), outputDo.getCompanyId());
                        ProductInfoDo productInfoDo = productInfoDao.selectById(productId);

                        for (StorageDo storageDo : storageDoList) {//遍历仓库是否都有库存
                            // LambdaQueryWrapper<StockRecordDo> wrapper2 = new LambdaQueryWrapper<>();
                            double[] size = mShipPriceService.countSameSkuSize(new double[4], productId, 1);
                            // wrapper2.eq(StockRecordDo::getShopId, outputDo.getShopId()).eq(StockRecordDo::getProductInfoId, productId).eq(StockRecordDo::getStorageId, storageDo.getId());
                            // StockRecordDo stockRecordDo1 = mStockRecordDao.selectOne(wrapper2);
                            int canUseCount = stockRecordService.getStockCount(outputDo.getCompanyId(), outputDo.getShopId(), storageDo.getId(), productId, productDo.getCount());
                            if (canUseCount >= productDo.getCount()) {
                                List<ShipPriceDo> shipPriceDos = mShipPriceService.queryByRegionAndSize(outputDo.getPostCode(), size, outputDo.getCod(), outputDo.getShipmentType(), storageDo.getId(), 1, outputDo.getCompanyId());
                                if (shipPriceDos.size() < 1 || shipPriceDos.get(0).getPrice() == 0) continue;
                                if (shipPirce > shipPriceDos.get(0).getPrice()) {//选择最便宜的价格
                                    shipPirce = shipPriceDos.get(0).getPrice();
                                    storageId = storageDo.getId();
                                }
                            }
                        }
                        if (storageId == 0) {
                            stringBuilderNoStock.append("(").append(productDo.getCommoditySku()).append(")");
                            continue;
                        }
                        OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                        productDetail.setProductId(productId);
                        productDetail.setCount(productDo.getCount());
                        productAddReqUploadList1.add(productDetail);
                        if (stringBuilder.length() > 0) stringBuilder.append(",");
                        stringBuilder.append(productInfoDo.getCommoditySku());
                        if (stringBuilder2.length() > 0) stringBuilder2.append(",");
                        stringBuilder2.append(productInfoDo.getStorageSku());
                        OrderOutputDo orderOutputDoNew = new OrderOutputDo();
                        BeanUtils.copyProperties(outputDo, orderOutputDoNew);
                        orderOutputDoNew.setStorageId(storageId);
                        save(orderOutputDoNew);
                        orderOutputDoNew.setOrderOutputNumber(OrderCodeUtil.getOrderOutNumber(orderOutputDoNew.getId()));
                        orderOutputDoNew.setStorageSku(productDo.getStorageSku());
                        orderOutputDoNew.setCommoditySku(productDo.getCommoditySku());

//                        for (OrderOutputProductAddReq productInfoDo1 : productAddReqUploadList1) {
                        OrderOutputPackageDo packageDo1 = new OrderOutputPackageDo();
                        packageDo1.setOrderOutputId(orderOutputDoNew.getId());
                        packageDo1.setCreateBy(orderOutputDoNew.getCreateBy());
                        packageDo1.setCreateTime(new Date());
                        packageDo1.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
                        packageDao.insert(packageDo1);
                        OrderOutputProductDo outputProductDo4 = new OrderOutputProductDo();
                        outputProductDo4.setProductId(productId);
                        outputProductDo4.setCount(productDo.getCount());
//        outputProductDo4.setCommoditySku(productInfoDo.getCommoditySku());
                        outputProductDo4.setOrderId(orderOutputDoNew.getId());
                        outputProductDo4.setPackageId(packageDo1.getId());
                        outputProductDo4.setCreateBy(orderOutputDoNew.getCreateBy());
                        outputProductDo4.setCreateTime(new Date());
                        outputProductDo4.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
                        productDao.insert(outputProductDo4);
//                        }
                        if (orderOutputDoNew.getStorageId() == 0) {
                            continue;
                        }
                        String value = updateTrackId(orderOutputDoNew);
                        if (value != null) {
                            throw new BizExceptionI18(value);
                        }
                    }
                    if (stringBuilderNoStock.length() > 0) {
                        throw new BizExceptionI18(SysConstant.Order_StockNotEnough, outputDo.getOrderNo(), stringBuilderNoStock.toString());
                    }
                }
            } else {
                //第一个默认仓库能发货
            }
            if (productAddReqUploadList.size() < 1) {
                dao.deleteById(outputDo.getId());
                return;
            }
            List<OrderOutputProductAddReq> productAddReqfilter = new ArrayList<>(productAddReqUploadList.stream().collect(Collectors.toMap(OrderOutputProductAddReq::getProductId, addReq1 -> addReq1, (o1, o2) -> {
                o1.setCount(o1.getCount() + o2.getCount());
                return o1;
            })).values());
            for (OrderOutputProductAddReq productInfoDo : productAddReqfilter) {
                OrderOutputProductDo outputProductDo4 = new OrderOutputProductDo();
                outputProductDo4.setProductId(productInfoDo.getProductId());
                outputProductDo4.setCount(productInfoDo.getCount());
//        outputProductDo4.setCommoditySku(productInfoDo.getCommoditySku());
                outputProductDo4.setOrderId(outputDo.getId());
                outputProductDo4.setPackageId(packageDo.getId());
                outputProductDo4.setCreateBy(outputDo.getCreateBy());
                outputProductDo4.setCreateTime(new Date());
                outputProductDo4.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
                productDao.insert(outputProductDo4);
            }
        }
//        threadPoolTaskExecutor.execute(() -> {
        outputDo.setOrderOutputNumber(OrderCodeUtil.getOrderOutNumber(outputDo.getId()));
        if (stringBuilder2.length() > 500) stringBuilder2.substring(0, 500);
        outputDo.setStorageSku(stringBuilder2.toString());
        if (stringBuilder.length() > 500) stringBuilder.substring(0, 500);
        outputDo.setCommoditySku(stringBuilder.toString());
        updateById(outputDo);
    }

    private String stringTrim(String address) {
        return address == null ? "" : address.replaceAll("\\n", "")
                .replaceAll("\\\"", "").replaceAll("，", "");
    }

    private String dealwithExcelData(int index, OrderOutputExcelImport excelData, Long shopId, int storageId, Long
            userid) {
        ShopDo shopDo = shopDao.selectById(shopId);
        if (shopDo == null) return StringsUtil.createI18Message(SysConstant.Shop_NotExist_Index);
        String value = checkOrderNo(excelData.getOrderNo(), shopDo.getCompanyId());
        String stringIndex = String.format("Line%d: ", index);
        if (value != null) {
            return StringsUtil.createI18Message(SysConstant.Order_OrderNo_Exist, excelData.getOrderNo());
        }
        OrderOutputDo outputDo = new OrderOutputDo();
        outputDo.setSendDate(new Date());
        outputDo.setStatus(DicBusinessItemConstant.outCreateState);
        if (StringUtils.isEmpty(excelData.getCommoditySku1()))
            return StringsUtil.createI18Message(SysConstant.Order_OrderNo_NoSkuMsg, excelData.getOrderNo());
        if ((excelData.getCount1()) < 1)
            return StringsUtil.createI18Message(SysConstant.PLS_INPUT_SKU_COUNT, excelData.getOrderNo());
        outputDo.setShopId(shopId);
        outputDo.setCompanyId(shopDo.getCompanyId());
        outputDo.setStorageId((long) storageId);
//        outputDo.setOrderType(1);
        String regEx = "[^0-9||-||^０-９||－]";
        Pattern p = Pattern.compile(regEx);
        if (StringUtils.isEmpty(excelData.getOrderNo()))
            return StringsUtil.createI18Message(SysConstant.Order_OrderNo_NotExist, excelData.getCommoditySku1());
        outputDo.setOrderNo(excelData.getOrderNo().trim().replaceAll("\\n", "").replaceAll("\\\"", "").replaceAll(",", "").replaceAll("，", ""));
        outputDo.setCreateBy(userid);
        outputDo.setCreateTime(new Date());
        if (StringUtils.isEmpty(excelData.getPostCode()))
            return StringsUtil.createI18Message(SysConstant.Order_NoZipCode, excelData.getOrderNo());
        outputDo.setPostCode(excelData.getPostCode().trim().replaceAll("\\n", "").replaceAll("\\\"", "").replaceAll(",", "").replaceAll("，", ""));
        Matcher m = p.matcher(outputDo.getPostCode());
        String post2 = m.replaceAll("").trim();
        outputDo.setPostCode(post2);
        if (StringUtils.isNotBlank(excelData.getTelPhone())) {
            outputDo.setTelPhone(excelData.getTelPhone().trim().replaceAll("\\n", "").replaceAll("\\\"", "").replaceAll(",", "").replaceAll("，", "").replaceAll("\\+81", ""));
            Matcher m1 = p.matcher(outputDo.getTelPhone());
            String post1 = m1.replaceAll("").replaceAll("\\+81", "").trim();
            outputDo.setTelPhone(post1.trim());
        }
        JpRegionDo jpRegionDo = regionService.getRegionDoByPostCode(post2);
        if (jpRegionDo != null) {
            outputDo.setAreaId(jpRegionDo.getId());
            outputDo.setArea(jpRegionDo.getName());
        } else {
            if (excelData.getArea() != null)
                outputDo.setArea(excelData.getArea().trim().replaceAll("\\n", "").replaceAll("\\\"", "").replaceAll(",", ""));
        }
        outputDo.setCreateTime(new Date());
        if (StringUtils.isEmpty(excelData.getAddress()))
            return StringsUtil.createI18Message(SysConstant.Order_NoAddress, excelData.getOrderNo());
        outputDo.setAddress(excelData.getAddress().replaceAll("\\n", "").replaceAll("\\\"", "").replaceAll(",", "").replaceAll("，", ""));
        if (StringUtils.isNotBlank(excelData.getReceiverName())) {
            outputDo.setReceiverName(excelData.getReceiverName().replaceAll("\\n", "").replaceAll("\\\"", "").replaceAll(",", "").replaceAll("，", ""));
            if (outputDo.getReceiverName().length() > 50) {
                return StringsUtil.createI18Message(SysConstant.Order_Name_TooLong, excelData.getOrderNo());
            }
        }
//        if (excelData.getDeliveryDate()!=null)
//            outputDo.setDeliveryDate(excelData.getDeliveryDate());
        if (StringUtils.isNotBlank(excelData.getDeliveryDate())) {
            try {
                Date deliveryDate = TimeUtils.parseDate(excelData.getDeliveryDate());
                //指定次日配达，把订单改成次日达订单
                Date currentDate = TimeUtils.parseDate(TimeUtils.getCurrentDateFormat());
                int currentHour = Integer.parseInt(TimeUtils.getCurrentDateFormat("HH"));
                if (currentHour < 12) {
                    if (deliveryDate.getTime() - currentDate.getTime() <= 24 * 60 * 60 * 1000) {
                        excelData.setDeliveryDate(TimeUtils.getCurrentDateFormat(1));
                        excelData.setShipmentType(SHIPMENT_TYPE_1);
                    }
                } else {
                    if (deliveryDate.getTime() - currentDate.getTime() <= 48 * 60 * 60 * 1000) {
                        excelData.setDeliveryDate(TimeUtils.getCurrentDateFormat(2));
                        excelData.setShipmentType(SHIPMENT_TYPE_1);
                    }
                }
                if (TimeUtils.parseDate(excelData.getDeliveryDate()).getTime() - System.currentTimeMillis() > 1000 * 60 * 60 * 24 * 14) {
                    return StringsUtil.createI18Message(SysConstant.MAX_DELIVERY_DAY_14);
                }
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

                Date date = dateFormat.parse(excelData.getDeliveryDate());
                outputDo.setDeliveryDate(date);
            } catch (ParseException e) {
                e.printStackTrace();
                return StringsUtil.createI18Message(SysConstant.Order_ErrDateFormat, excelData.getOrderNo());
            }
        }
        if (StringUtils.isNotBlank(excelData.getDeliveryTime())) {
            outputDo.setDeliveryTime(excelData.getDeliveryTime().replaceAll("时", "").replaceAll("時", ""));
        }
        if (excelData.getTips() != null && (excelData.getTips().contains("西浓") || excelData.getTips().contains("西濃") || excelData.getTips().contains("seino"))) {
            outputDo.setTrackId(DicBusinessItemConstant.xinongExpress);
        }
        outputDo.setTips(excelData.getTips());
        outputDo.setCod(excelData.getCod());
        if (SHIPMENT_TYPE_1.equals(excelData.getShipmentType())) {
            outputDo.setShipmentType(1);
        } else if (SHIPMENT_TYPE_2.equals(excelData.getShipmentType())) {
            outputDo.setShipmentType(0);
            outputDo.setTrackId(StaticDict.Track_Type.YamatoExpressJCB.getValue());
        } else {
            outputDo.setShipmentType(0);
        }

        save(outputDo);
        try {
            dealwithExcelProduct(stringIndex, outputDo, excelData, shopDo.getCompanyId());
        } catch (BizException e) {
            e.printStackTrace();
            dao.deleteById(outputDo.getId());
            return StringsUtil.createI18Message(e.getErrorMsg(), e.getArgs());
        }
        return null;
    }

    private String checkOrderNo(String orderNo, Long companyId) {
        LambdaQueryWrapper<OrderOutputDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderOutputDo::getOrderNo, orderNo)
                .eq(OrderOutputDo::getCompanyId, companyId);
        wrapper.and(new Consumer<LambdaQueryWrapper<OrderOutputDo>>() {
            @Override
            public void accept(LambdaQueryWrapper<OrderOutputDo> orderOutputDoLambdaQueryWrapper) {
                orderOutputDoLambdaQueryWrapper.lt(OrderOutputDo::getStatus, DicBusinessItemConstant.outHasRecovered).or()
                        .gt(OrderOutputDo::getStatus, DicBusinessItemConstant.orderCutOff);
            }
        });
        int count = baseMapper.selectCount(wrapper);
        if (count < 1) {
            return null;
        } else {
            return StringsUtil.createI18Message(SysConstant.ORDER_NUMBER_EXIST, orderNo);
//            return "订单已存在";
        }
    }

    private String checkOrderNo(String orderNo, Long companyId, List<OrderOutputProductAddReq> productList) {
        LambdaQueryWrapper<OrderOutputDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(OrderOutputDo::getId).eq(OrderOutputDo::getOrderNo, orderNo)
                .ge(OrderOutputDo::getSendDate, TimeUtils.getCurrentDateFormat(-30))
                .eq(OrderOutputDo::getCompanyId, companyId);
        if (productList.size() == 1) {
            String sku = "";
            if (productList.get(0).getProductId() == null) {
                sku = productList.get(0).getCommoditySku();
            } else {
                ProductInfoDo productInfoDo = productInfoDao.selectById(productList.get(0).getProductId());
                if (productInfoDo != null) {
                    sku = productInfoDo.getCommoditySku();
                }
            }
            wrapper.eq(OrderOutputDo::getCommoditySku, sku);
        }
        List<Object> list = baseMapper.selectObjs(wrapper);
        if (list == null || list.size() < 1) {
            return null;
        } else if (productList.size() == 1) {
            return StringsUtil.createI18Message(SysConstant.ORDER_SKU_EXIST, orderNo, productInfoDao.selectById(productList.get(0).getProductId()).getCommoditySku());
//            return String.format("%s(%s)已存在", orderNo, productInfoDao.selectById(productList.get(0).getProductId()).getCommoditySku());
        } else {
            for (Object orderOutputId : list) {
                for (OrderOutputProductAddReq productAdd : productList) {
                    LambdaQueryWrapper<OrderOutputProductDo> productWrapper = new LambdaQueryWrapper<>();
                    productWrapper.eq(OrderOutputProductDo::getProductId, productAdd.getProductId());
                    productWrapper.eq(OrderOutputProductDo::getOrderId, orderOutputId);
                    List<OrderOutputProductDo> productDoList = productDao.selectList(productWrapper);
                    if (productDoList != null && productDoList.size() > 0) {
                        return StringsUtil.createI18Message(SysConstant.ORDER_SKU_EXIST, orderNo, productInfoDao.selectById(productList.get(0).getProductId()).getCommoditySku());
//                        return String.format("%s(%s)已存在", orderNo, productInfoDao.selectById(productAdd.getProductId()).getCommoditySku());
                    }
                }
            }
            return null;
        }
    }

    private void dealwithExcelProduct(String stringIndex, OrderOutputDo outputDo, OrderOutputExcelImport
            excelData, Long companyId) {

//        outputDo.setStorageId(0L);
        OrderOutputPackageDo packageDo = new OrderOutputPackageDo();
        packageDo.setOrderOutputId(outputDo.getId());
        packageDo.setCreateBy(outputDo.getCreateBy());
        packageDo.setCreateTime(new Date());
        packageDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
        packageDao.insert(packageDo);
        StringBuilder stringBuilder = new StringBuilder();
        int count = 0;
        StringBuilder stringBuilder2 = new StringBuilder();
        int dGoods = 0;//危险品
        if (outputDo.getStorageId() != 0) {
            List<OrderOutputProductAddReq> productInfoDoList = new ArrayList<>();
            //todo 产品数量过多时需要人工审核，状态改为-1
            if (StringUtils.isNotBlank(excelData.getCommoditySku1())) {
                productInfoDoList.addAll(dealwithExcelProductAndStock(outputDo, packageDo.getId(), stringIndex,
                        excelData.getCount1(), excelData.getCommoditySku1(), companyId));
                // for (OrderOutputProductAddReq orderOutputProductAddReq : productInfoDoList) {
                //     if (stringBuilder.length() > 0) stringBuilder.append(",");
                //     stringBuilder.append(orderOutputProductAddReq.getCommoditySku());
                //     if (stringBuilder2.length() > 0) stringBuilder.append(",");
                //     stringBuilder2.append(orderOutputProductAddReq.getStorageSku());
                // }
            } else {
                throw new BizExceptionI18(SysConstant.Product_NotExist_Index, stringIndex, excelData.getCommoditySku1());
            }
            //产品2
            if (StringUtils.isNotBlank(excelData.getCommoditySku2())) {
                productInfoDoList.addAll(dealwithExcelProductAndStock(outputDo, packageDo.getId(), stringIndex,
                        excelData.getCount2(), excelData.getCommoditySku2(), companyId));
            }
            //产品3
            if (StringUtils.isNotBlank(excelData.getCommoditySku3())) {
                productInfoDoList.addAll(dealwithExcelProductAndStock(outputDo, packageDo.getId(), stringIndex,
                        excelData.getCount3(), excelData.getCommoditySku3(), companyId));
            }
            //产品4
            if (StringUtils.isNotBlank(excelData.getCommoditySku4())) {
                productInfoDoList.addAll(dealwithExcelProductAndStock(outputDo, packageDo.getId(), stringIndex,
                        excelData.getCount4(), excelData.getCommoditySku4(), companyId));
            }

            List<OrderOutputProductAddReq> productAddReqfilter = new ArrayList<>(productInfoDoList.stream().collect(Collectors.toMap(OrderOutputProductAddReq::getProductId, addReq1 -> addReq1, (o1, o2) -> {
                o1.setCount(o1.getCount() + o2.getCount());
                return o1;
            })).values());
            for (OrderOutputProductAddReq orderOutputProductAddReq : productAddReqfilter) {
                if (stringBuilder.length() > 0) stringBuilder.append(",");
                stringBuilder.append(orderOutputProductAddReq.getCommoditySku());
                if (stringBuilder2.length() > 0) stringBuilder.append(",");
                stringBuilder2.append(orderOutputProductAddReq.getStorageSku());
                OrderOutputProductDo outputProductDo1 = new OrderOutputProductDo();
                outputProductDo1.setProductId(orderOutputProductAddReq.getProductId());
                outputProductDo1.setCount(orderOutputProductAddReq.getCount());
                count += orderOutputProductAddReq.getCount();
                outputProductDo1.setOrderId(outputDo.getId());
                outputProductDo1.setPackageId(packageDo.getId());
                outputProductDo1.setCreateBy(outputDo.getCreateBy());
                outputProductDo1.setCreateTime(new Date());
                outputProductDo1.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
                verifyStock(outputDo.getCompanyId(), outputDo.getShopId(), outputDo.getStorageId(),
                        outputProductDo1.getProductId(), outputProductDo1.getCount(), orderOutputProductAddReq.getCommoditySku());
                productDao.insert(outputProductDo1);
            }
        } else {//不指定仓库，系统自动选择
            List<OrderOutputProductAddReq> productAddReqList = new ArrayList<>();
            List<OrderOutputProductAddReq> productAddReqUploadList = new ArrayList<>();
            OrderOutputProductAddReq addReq = new OrderOutputProductAddReq();
            addReq.setCommoditySku(excelData.getCommoditySku1());
            addReq.setCount(excelData.getCount1());
            productAddReqList.add(addReq);
            if (StringUtils.isNotBlank(excelData.getCommoditySku2())) {
                addReq = new OrderOutputProductAddReq();
                addReq.setCommoditySku(excelData.getCommoditySku2());
                addReq.setCount(excelData.getCount2());
                productAddReqList.add(addReq);
            }
            if (StringUtils.isNotBlank(excelData.getCommoditySku3())) {
                addReq = new OrderOutputProductAddReq();
                addReq.setCommoditySku(excelData.getCommoditySku3());
                addReq.setCount(excelData.getCount3());
                productAddReqList.add(addReq);
            }
            if (StringUtils.isNotBlank(excelData.getCommoditySku4())) {
                addReq = new OrderOutputProductAddReq();
                addReq.setCommoditySku(excelData.getCommoditySku4());
                addReq.setCount(excelData.getCount4());
                productAddReqList.add(addReq);
            }
            long storageId = 0L;
            //自动分配仓库
            Long stateId = regionService.getStateIdByPostCode(outputDo.getPostCode());
            // if (stateId <= 7 || (stateId != 9 && companyId == 32)) {//大阪地区优先发货仓库
            //     storageId = 12L;
            // } else if (stateId >= 8) {//东京仓库优先发货仓库
            storageId = 15L;
            // }
            long lastStorageId = storageId;
            for (OrderOutputProductAddReq productDo : productAddReqList) {//多个产品判断
                Long productId = getProductId(productDo.getCommoditySku(), outputDo.getCompanyId());
                ProductInfoDo productInfoDo = productInfoDao.selectById(productId);
                if (productId == null)
                    throw new BizExceptionI18(SysConstant.Order_SkuNotfound, outputDo.getOrderNo(), productDo.getCommoditySku());
                try {
                    verifyStock(outputDo.getCompanyId(), outputDo.getShopId(), storageId, productId, productDo.getCount(), productDo.getCommoditySku());
                    OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                    productDetail.setProductId(productId);
                    productDetail.setCount(productDo.getCount());
                    count += productDetail.getCount();
                    if (stringBuilder.length() > 0) stringBuilder.append(",");
                    stringBuilder.append(productDo.getCommoditySku());
                    if (stringBuilder2.length() > 0) stringBuilder2.append(",");
                    stringBuilder2.append(productInfoDo.getStorageSku());
                    productAddReqUploadList.add(productDetail);
                } catch (Exception e) {
                    e.printStackTrace();
                    storageId = 0;
                }

            }
            outputDo.setStorageId(storageId);
            //一个仓库是否发完所有订单
            if (storageId == 0) {
                List<OrderRakutenProductDo> productDoListFailed = new ArrayList<>();
                LambdaQueryWrapper<StorageDo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(StorageDo::getSupportShip, 1).ne(StorageDo::getId, lastStorageId);
                if (stateId <= 7 || (stateId != 9 && companyId == 32)) {
                    lambdaQueryWrapper.orderByDesc(StorageDo::getStorageArea);
                } else {
                    lambdaQueryWrapper.orderByAsc(StorageDo::getStorageArea);
                }
                List<StorageDo> storageDos = storageDao.selectList(lambdaQueryWrapper);
                storageId = 0L;
                if (storageDos != null) {
                    kk:
                    for (StorageDo storageDo : storageDos) {
                        //遍历支持捆包仓库是否都有库存
                        for (OrderOutputProductAddReq productDo : productAddReqList) {//多个产品判断
                            Long productId = getProductId(productDo.getCommoditySku(), outputDo.getCompanyId());
                            ProductInfoDo productInfoDo = productInfoDao.selectById(productId);
                            if (productId == null)
                                throw new BizException(SysConstant.Order_SkuNotfound, outputDo.getOrderNo(), productDo.getCommoditySku());
                            try {
                                verifyStock(outputDo.getCompanyId(), outputDo.getShopId(), storageDo.getId(), productId, productDo.getCount(), productDo.getCommoditySku());
                                OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                                productDetail.setProductId(productId);
                                productDetail.setCount(productDo.getCount());
                                count += productDetail.getCount();
                                if (stringBuilder.length() > 0) stringBuilder.append(",");
                                stringBuilder.append(productInfoDo.getCommoditySku());
                                if (stringBuilder2.length() > 0) stringBuilder2.append(",");
                                stringBuilder2.append(productInfoDo.getStorageSku());
                                productAddReqUploadList.add(productDetail);
                            } catch (Exception e) {
                                e.printStackTrace();
                                storageId = 0;
                                productAddReqUploadList.clear();
                                continue kk;
                            }

                        }
                        storageId = storageDo.getId();
                        break kk;
                    }
                    outputDo.setStorageId(storageId);
                }
                if (storageId == 0) {//捆包仓库无库存，分别发
                    LambdaQueryWrapper<StorageDo> queryWrapper = new LambdaQueryWrapper<>();
                    List<OrderOutputProductAddReq> productAddReqUploadList1 = new ArrayList<>();
                    queryWrapper.eq(StorageDo::getCountryType, 1);
                    List<StorageDo> storageDoList = storageDao.selectList(queryWrapper);
                    StringBuilder stringBuilderNoStock = new StringBuilder();
                    for (OrderOutputProductAddReq productDo : productAddReqList) {
                        storageId = 0L;
                        double shipPirce = 99999D;
                        Long productId = getProductId(productDo.getCommoditySku(), outputDo.getCompanyId());
                        ProductInfoDo productInfoDo = productInfoDao.selectById(productId);

                        for (StorageDo storageDo : storageDoList) {//遍历仓库是否都有库存
                            // LambdaQueryWrapper<StockRecordDo> wrapper2 = new LambdaQueryWrapper<>();
                            double[] size = mShipPriceService.countSameSkuSize(new double[4], productId, 1);
                            // wrapper2.eq(StockRecordDo::getShopId, outputDo.getShopId()).eq(StockRecordDo::getProductInfoId, productId).eq(StockRecordDo::getStorageId, storageDo.getId());
                            // StockRecordDo stockRecordDo1 = mStockRecordDao.selectOne(wrapper2);
                            int canUseCount = stockRecordService.getStockCount(outputDo.getCompanyId(), outputDo.getShopId(), storageDo.getId(), productId, productDo.getCount());
                            if (canUseCount >= productDo.getCount()) {
                                List<ShipPriceDo> shipPriceDos = mShipPriceService.queryByRegionAndSize(outputDo.getPostCode(), size, outputDo.getCod(), outputDo.getShipmentType(), storageDo.getId(), 1, outputDo.getCompanyId());
                                if (shipPriceDos.size() < 1 || shipPriceDos.get(0).getPrice() == 0) continue;
                                if (shipPirce > shipPriceDos.get(0).getPrice()) {//选择最便宜的价格
                                    shipPirce = shipPriceDos.get(0).getPrice();
                                    storageId = storageDo.getId();
                                }
                            }
                        }
                        if (storageId == 0) {
                            stringBuilderNoStock.append("(").append(productDo.getCommoditySku()).append(")");
                            continue;
                        }
                        OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                        productDetail.setProductId(productId);
                        productDetail.setCount(productDo.getCount());
                        count += productDetail.getCount();
                        productAddReqUploadList1.add(productDetail);
                        if (stringBuilder.length() > 0) stringBuilder.append(",");
                        stringBuilder.append(productInfoDo.getCommoditySku());
                        if (stringBuilder2.length() > 0) stringBuilder2.append(",");
                        stringBuilder2.append(productInfoDo.getStorageSku());
                        OrderOutputDo orderOutputDoNew = new OrderOutputDo();
                        BeanUtils.copyProperties(outputDo, orderOutputDoNew);
                        orderOutputDoNew.setStorageId(storageId);
                        save(orderOutputDoNew);
                        orderOutputDoNew.setOrderOutputNumber(OrderCodeUtil.getOrderOutNumber(orderOutputDoNew.getId()));
                        orderOutputDoNew.setStorageSku(productDo.getStorageSku());
                        orderOutputDoNew.setCommoditySku(productDo.getCommoditySku());

//                        for (OrderOutputProductAddReq productInfoDo1 : productAddReqUploadList1) {
                        OrderOutputPackageDo packageDo1 = new OrderOutputPackageDo();
                        packageDo1.setOrderOutputId(orderOutputDoNew.getId());
                        packageDo1.setCreateBy(orderOutputDoNew.getCreateBy());
                        packageDo1.setCreateTime(new Date());
                        packageDo1.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
                        packageDao.insert(packageDo1);
                        OrderOutputProductDo outputProductDo4 = new OrderOutputProductDo();
                        outputProductDo4.setProductId(productId);
                        outputProductDo4.setCount(productDo.getCount());
//        outputProductDo4.setCommoditySku(productInfoDo.getCommoditySku());
                        outputProductDo4.setOrderId(orderOutputDoNew.getId());
                        outputProductDo4.setPackageId(packageDo1.getId());
                        outputProductDo4.setCreateBy(orderOutputDoNew.getCreateBy());
                        outputProductDo4.setCreateTime(new Date());
                        outputProductDo4.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
                        productDao.insert(outputProductDo4);
//                        }
                        if (orderOutputDoNew.getStorageId() == 0) {
                            continue;
                        }
                        String value = updateTrackId(orderOutputDoNew);
                        if (value != null) {
                            throw new BizExceptionI18(value);
                        }
                    }
                    if (stringBuilderNoStock.length() > 0) {
                        throw new BizExceptionI18(SysConstant.Order_StockNotEnough, outputDo.getOrderNo(), stringBuilderNoStock.toString());
                    }
                }
            } else {
                //第一个默认仓库能发货
            }
            if (productAddReqUploadList.size() < 1) {
                dao.deleteById(outputDo.getId());
                return;
            }
            List<OrderOutputProductAddReq> productAddReqfilter = new ArrayList<>(productAddReqUploadList.stream().collect(Collectors.toMap(OrderOutputProductAddReq::getProductId, addReq1 -> addReq1, (o1, o2) -> {
                o1.setCount(o1.getCount() + o2.getCount());
                return o1;
            })).values());
            for (OrderOutputProductAddReq productInfoDo : productAddReqfilter) {
                OrderOutputProductDo outputProductDo4 = new OrderOutputProductDo();
                outputProductDo4.setProductId(productInfoDo.getProductId());
                outputProductDo4.setCount(productInfoDo.getCount());
//        outputProductDo4.setCommoditySku(productInfoDo.getCommoditySku());
                outputProductDo4.setOrderId(outputDo.getId());
                outputProductDo4.setPackageId(packageDo.getId());
                outputProductDo4.setCreateBy(outputDo.getCreateBy());
                outputProductDo4.setCreateTime(new Date());
                outputProductDo4.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
                productDao.insert(outputProductDo4);
            }
        }
//        threadPoolTaskExecutor.execute(() -> {

        operateRecordDao.operateAddRecord(SysConstant.IMPORT_ORDER_SUCCESS, outputDo.getId(), outputDo.getCreateBy(), 3);
        outputDo.setOrderOutputNumber(OrderCodeUtil.getOrderOutNumber(outputDo.getId()));
        if (stringBuilder2.length() > 500) stringBuilder2.substring(0, 500);
        outputDo.setStorageSku(stringBuilder2.toString());
        if (stringBuilder.length() > 500) stringBuilder2.substring(0, 500);
        outputDo.setCommoditySku(stringBuilder.toString());
        outputDo.setOrderType(count > 2 ? 2 : 1);
        String value = updateTrackId(outputDo);
        if (value != null) {
            throw new BizExceptionI18(SysConstant.Order_Create_Fair_Manual, outputDo.getOrderNo());
        }
        StorageDo storageDo = storageDao.selectById(outputDo.getStorageId());
        this.dealwithPrintLabelPackageInfo(outputDo, storageDo, outputDo.getCreateBy());
    }

    private List<OrderOutputProductAddReq> dealwithExcelProductAndStock(OrderOutputDo orderOutputDo, Long
            packageDoId, String stringIndex, int count1, String commoditySku1, Long companyId) {
        ProductInfoDo productInfoDo = productInfoDao.selectById(getProductId(commoditySku1, companyId));
        if (productInfoDo == null)
            throw new BizExceptionI18(SysConstant.Product_NotExist_Index, stringIndex, commoditySku1);
        if (count1 < 1)
            throw new BizExceptionI18(SysConstant.Product_QuantityLess_Index, stringIndex, commoditySku1);
        List<OrderOutputProductAddReq> itemAddReqList = new ArrayList<>();
        LambdaQueryWrapper<ProductCombinationDo> productCombinationWrapper = new LambdaQueryWrapper<>();
        productCombinationWrapper.eq(ProductCombinationDo::getParentId, productInfoDo.getId());
        List<ProductCombinationDo> productCombinationDoList = productCombinationService.getBaseMapper().selectList(productCombinationWrapper);
        for (ProductCombinationDo productCombinationDo : productCombinationDoList) {
            if (productCombinationDo.getEffective() == 1) {
                if (productCombinationDo.getEffectBeginTime() == null || productCombinationDo.getEffectEndTime() == null)
                    continue;
                if (orderOutputDo.getCreateTime().getTime() < productCombinationDo.getEffectBeginTime().getTime()
                        || orderOutputDo.getCreateTime().getTime() > productCombinationDo.getEffectEndTime().getTime())
                    continue;
            }
            OrderOutputProductAddReq productDo1 = new OrderOutputProductAddReq();
            ProductInfoDo productInfoDo1 = productInfoService.getById(productCombinationDo.getChildId());
            if (productInfoDo1 == null) {
                throw new BizExceptionI18(SysConstant.Product_Combination_Notfound_Index, stringIndex, productInfoDo.getCommoditySku());
            }
            productDo1.setProductId(productCombinationDo.getChildId());
            productDo1.setCommoditySku(productInfoDo1.getCommoditySku());
            productDo1.setCount(productCombinationDo.getCount() * count1);
            itemAddReqList.add(productDo1);
        }
        if (!productInfoDo.getTypeOfProduct().equals(StaticDict.Product_Info_Type.Combination.getValue())) {
            OrderOutputProductAddReq productDo1 = new OrderOutputProductAddReq();
            productDo1.setProductId(productInfoDo.getId());
            productDo1.setCommoditySku(productInfoDo.getCommoditySku());
            productDo1.setCount(count1);
            itemAddReqList.add(productDo1);
        }
        return itemAddReqList;
    }


    @Override
    public double[] getMaxPackageSize(Long storageId, List<OrderOutputProductDo> productDoList,
                                      boolean split, Long trackId, Long companyId, Map<Long, ProductInfoDo> productmMap, StorageDo storageDo) {
        double[] packageSize = new double[8];
        if ("0".equals(storageDo.getSupportShip())) {
            ProductInfoDo productInfoDo = productInfoDao.selectById(productDoList.get(0).getProductId());
            if (productInfoDo != null) {
                packageSize[0] = productInfoDo.getLength();
                packageSize[1] = productInfoDo.getWidth();
                packageSize[2] = productInfoDo.getHeight();
                packageSize[3] = productInfoDo.getWeight();
                packageSize[4] = 0;
            }
        } else {
            List<OrderOutputPackageDetailDo> packageDoDetailList = this.getPackageSizeInfoCount(productDoList, split, trackId, storageId, companyId, productmMap);
            //捆包多尺寸信息，选最大尺寸展示  耗材也要比较
            for (OrderOutputPackageDetailDo orderOutputDetailDo : packageDoDetailList) {
                boolean isMaterial = orderOutputDetailDo.getMaterialId() != null && orderOutputDetailDo.getMaterialId() != -1L;//判断是否 有包装耗材
                //取三边和。如果是耗材 就去耗材三遍 如果没有耗材 则取 原产品尺寸三边和
                double packSize = isMaterial ? (orderOutputDetailDo.getMLength() + orderOutputDetailDo.getMWidth() + orderOutputDetailDo.getMHeight()) : (orderOutputDetailDo.getLength() + orderOutputDetailDo.getWidth() + orderOutputDetailDo.getHeight());
                boolean materialSizeBig = packSize > (packageSize[0] + packageSize[1] + packageSize[2]); //是否 包装耗材尺寸大
                packageSize[0] = (materialSizeBig ? (isMaterial ? orderOutputDetailDo.getMLength() : orderOutputDetailDo.getLength()) : packageSize[0]);
                packageSize[1] = (materialSizeBig ? (isMaterial ? orderOutputDetailDo.getMWidth() : orderOutputDetailDo.getWidth()) : packageSize[1]);
                packageSize[2] = (materialSizeBig ? (isMaterial ? orderOutputDetailDo.getMHeight() : orderOutputDetailDo.getHeight()) : packageSize[2]);
                packageSize[3] = Math.max(orderOutputDetailDo.getWeight(), packageSize[3]);//重量不管 谁的三边和大 永远取两者重量最大值
                packageSize[4] = materialSizeBig ? (orderOutputDetailDo.getMaterialId() == null ? 0 : orderOutputDetailDo.getMaterialId()) : packageSize[4];
                packageSize[5] = materialSizeBig ? orderOutputDetailDo.getLength() : packageSize[5];// 567 放的原产品尺寸
                packageSize[6] = materialSizeBig ? orderOutputDetailDo.getWidth() : packageSize[6];
                packageSize[7] = materialSizeBig ? orderOutputDetailDo.getHeight() : packageSize[7];
            }
        }
        //耗材包装尺寸
        double[] sortSize = mShipPriceService.getSizeOrderDesc(packageSize[0], packageSize[1], packageSize[2]);
        packageSize[0] = sortSize[0];
        packageSize[1] = sortSize[1];
        packageSize[2] = sortSize[2];
        //原包装尺寸
        double[] oldSize = mShipPriceService.getSizeOrderDesc(packageSize[5], packageSize[6], packageSize[7]);
        packageSize[5] = oldSize[0];
        packageSize[6] = oldSize[1];
        packageSize[7] = oldSize[2];

        return packageSize;
    }

    private String updateTrackId(OrderOutputDo outputDo) {
        StorageDo storageDo = storageDao.selectById(outputDo.getStorageId());
        return this.updateTrackId(outputDo, new ArrayList<>(), new ArrayList<>(), null, storageDo);
    }

    private String updateTrackId(OrderOutputDo outputDo, List<OrderOutputProductDo> productDoList, List<OrderOutputPackageDo> packageDoList, Map<Long, ProductInfoDo> productmMap, StorageDo storageDo) {
        if (productDoList.isEmpty() || packageDoList.isEmpty()) {
            int count = 0;
            do {
                QueryWrapper<OrderOutputProductDo> wrapper = new QueryWrapper<>();
                wrapper.eq("order_id", outputDo.getId());
                productDoList = productDao.selectList(wrapper);
                QueryWrapper<OrderOutputPackageDo> wrapper1 = new QueryWrapper<>();
                wrapper1.eq("order_output_id", outputDo.getId());
                packageDoList = packageDao.selectList(wrapper1);
                count++;
                if (count > 20) return StringsUtil.createI18Message(SysConstant.Order_Create_Fair);
                if (count > 3) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            } while (productDoList.isEmpty() || packageDoList.isEmpty());
        }
        if (productmMap == null) {
            List<Long> productIds = productDoList.stream().map(OrderOutputProductDo::getProductId).distinct().collect(Collectors.toList());
            if (!productIds.isEmpty()) {
                List<ProductInfoDo> productBeans = productInfoDao.selectList(new LambdaQueryWrapper<ProductInfoDo>()
                        .in(ProductInfoDo::getId, productIds));
                productmMap = productBeans.stream().collect(Collectors.toMap(ProductInfoDo::getId, i -> i, (v1, v2) -> v1));
            } else {
                productmMap = new HashMap<>();
            }
        }
        //获取商品最大尺寸
        OrderOutputPackageDo packageDo = packageDoList.get(0);
        double[] packageSize = this.getMaxPackageSize(outputDo.getStorageId(), productDoList, StringUtils.isBlank(outputDo.getTrackNumber()), outputDo.getTrackId(), outputDo.getCompanyId(), productmMap, storageDo);
        packageDo.setLength(packageSize[0]);
        packageDo.setWidth(packageSize[1]);
        packageDo.setHeight(packageSize[2]);
        packageDo.setWeight(packageSize[3]);
        packageDo.setCount(1);

        //1370优先指定发盒子
        if ((outputDo.getCompanyId().intValue() == 370 && outputDo.getTrackId() == null)) {
            outputDo.setStatus(DicBusinessItemConstant.outCreateCheckState);
            List<Map<String, Object>> trackList = mShipPriceService.getTrackList(productDoList, outputDo.getStorageId(), outputDo.getPostCode(),
                    outputDo.getShipmentType(), outputDo.getCod() == null ? 0 : outputDo.getCod(), outputDo.getCompanyId());
            if (!trackList.isEmpty()) {
                boolean isbox = false;
                if (DicBusinessItemConstant.yamatoExpress.equals((Long) trackList.get(0).get("id"))) {
                    for (Map<String, Object> stringObjectMap : trackList) {
                        if (stringObjectMap.get("id").equals(DicBusinessItemConstant.yamatoExpressBox)) {
                            outputDo.setTrackId(DicBusinessItemConstant.yamatoExpressBox);
                            isbox = true;
                            break;
                        }
                    }
                }
                if (!isbox)
                    outputDo.setTrackId((Long) trackList.get(0).get("id"));

            } else {
                outputDo.setTrackId(DicBusinessItemConstant.yamatoExpress);
            }
        } else if ("1".equals(storageDo.getSupportShip())) {
            if (outputDo.getTrackId() != null && outputDo.getTrackId() != 0) {
                //如果指定了trackId ，看子类trackId中最优项
                List<Long> idByParentId = dicBusinessItemService.getIdByParentId(DicBusinessConstant.trackCompany, outputDo.getTrackId());
                ShipPriceDo priceDo = null;
                if (!idByParentId.isEmpty()) {
                    for (Long aLong : idByParentId) {
                        ShipPriceDo ship = mShipPriceService.queryByRegionAndSize(outputDo.getPostCode(), packageSize, outputDo.getCod(), outputDo.getCompanyId().intValue() == 591 ? 0 : outputDo.getShipmentType(), outputDo.getStorageId(), aLong, 1, 0, outputDo.getCompanyId());
                        if (ship == null) continue;
                        if (priceDo == null || priceDo.getPrice() > ship.getPrice()) {
                            priceDo = ship;
                            outputDo.setTrackId(aLong);
                        }
                    }
                } else {
                    priceDo = mShipPriceService.queryByRegionAndSize(outputDo.getPostCode(), packageSize, outputDo.getCod(), outputDo.getCompanyId().intValue() == 591 ? 0 : outputDo.getShipmentType(), outputDo.getStorageId(), outputDo.getTrackId(), 1, 0, outputDo.getCompanyId());
                }
                if (priceDo == null) {
                    outputDo.setTrackId(null);
                    return updateTrackId(outputDo);
                }
                outputDo.setStatus(DicBusinessItemConstant.outCreateCheckState);
            } else {
                List<ShipPriceDo> shipPrices = mShipPriceService.queryByRegionAndSize(outputDo.getPostCode(), packageSize, outputDo.getCod(), outputDo.getCompanyId().intValue() == 591 ? 0 : outputDo.getShipmentType(), outputDo.getStorageId(), 1, 0, outputDo.getCompanyId());
                if (shipPrices == null || shipPrices.size() < 1) {
                    //未找到费用信息，请人工处理
                    outputDo.setStatus(DicBusinessItemConstant.outCreateCheckState);
                    outputDo.setTrackId(DicBusinessItemConstant.sagawaExpress);
                    //判断西农行不行
                    ShipPriceDo xiNong = mShipPriceService.queryByRegionAndSize(outputDo.getPostCode(), packageSize,
                            outputDo.getCod(), outputDo.getCompanyId().intValue() == 591 ? 0 : outputDo.getShipmentType(), outputDo.getStorageId(), DicBusinessItemConstant.xinongExpress, 1, 0, outputDo.getCompanyId());
                    if (xiNong != null) {
                        outputDo.setTrackId(DicBusinessItemConstant.xinongExpress);
                    }
//                    double[] size = mShipPriceService.getMulitSkuSize(productDoList);
//                    if (productDoList.size() == 1 && productDoList.get(0).getCount() == 1 && (size[0] + size[1] + size[2] > 260 || size[3] > 50)) {
//                        outputDo.setTrackId(DicBusinessItemConstant.xinongExpress);
//                        outputDo.setStatus(DicBusinessItemConstant.outCreateCheckState);
//                    }
                } else {
                    if (outputDo.getTrackId() == null || outputDo.getTrackId() == 0)
                        outputDo.setTrackId(mDimenDao.selectById(shipPrices.get(0).getDimensId()).getTrackId());
                    outputDo.setStatus(DicBusinessItemConstant.outCreateCheckState);
                }
            }

            //货到付款只支持mtb
//            if ((outputDo.getStorageId() == 10 || outputDo.getStorageId() == 11) && outputDo.getCod() != null && outputDo.getCod() != 0) {
//                outputDo.setTrackId(DicBusinessItemConstant.sagawaExpress);
//            }
        } else {
            outputDo.setStatus(DicBusinessItemConstant.outCreateCheckState);
            outputDo.setTrackId(DicBusinessItemConstant.sagawaExpress);
        }
        if (productDoList.size() == 1 && productDoList.get(0).getCount() == 1 &&
                (packageDo.getWidth() + packageDo.getHeight() + packageDo.getLength() <= 160 && packageDo.getWeight() <= 30) &&
                (outputDo.getCompanyId().intValue() == 216 || outputDo.getCompanyId().intValue() == 95)) {
            outputDo.setTrackId(DicBusinessItemConstant.sagawaExpress);
        }
        if ((DicBusinessItemConstant.yamatoExpress.equals(outputDo.getTrackId())
                || DicBusinessItemConstant.yamatoExpressSmall.equals(outputDo.getTrackId())) && isSeinoTrack(productDoList)) {
            outputDo.setTrackId(DicBusinessItemConstant.sagawaExpress);
        }
        if (outputDo.getCompanyId().intValue() == 201 || outputDo.getCompanyId().intValue() == 674) {
            outputDo.setTrackId(DicBusinessItemConstant.yamatoExpress);
        }
        // if (outputDo.getCompanyId().intValue() == 591 && Objects.equals(outputDo.getTrackId(), DicBusinessItemConstant.yamatoExpressBig)) {
        //     outputDo.setTrackId(DicBusinessItemConstant.yamatoExpress);
        // }
        if (Objects.equals(outputDo.getTrackId(), DicBusinessItemConstant.yamatoExpressBox)) {
            //黑猫盒子
            packageDo.setLength(packageSize[5]);
            packageDo.setWidth(packageSize[6]);
            packageDo.setHeight(packageSize[7]);
        }
        packageDao.updateById(packageDo);
        if (StringUtils.isBlank(outputDo.getOrderOutputNumber())) {
            outputDo.setOrderOutputNumber(OrderCodeUtil.getOrderOutNumber(outputDo.getId()));
        }
        updateById(outputDo);
        return null;
    }
    //
    // @Override
    // public int jugSizeType(double[] size, Long storageId, List<OrderOutputProductDo> productDoList) {
    //     boolean flag = verifyMaxSize(productDoList, size, storageId);//判断捆包超不超过尺寸
    //     if (flag) {//捆包尺寸超大
    //         return 0;
    //     } else {
    //         if ((productDoList.size() == 1 && productDoList.get(0).getCount() == 1)) {//一单一件
    //             return 3;
    //         } else {//一单多件
    //             return 2;
    //         }
    //     }
    // }

    /**
     * 判断 是否是 黑猫小包的size
     *
     * @return
     */
    @Override
    public boolean yamatoExpressSmallSize(double[] size, Long storageId, Integer cod, Integer shipmentType) {
//        return size[0] + size[1] + size[2] < 60 && size[3] < 1 && size[0] < 31.2 && size[1] < 22.8 && size[2] < 2.5
//                && (storageId == 10 || storageId == 11) && (cod == null || cod == 0)
//                && (shipmentType == null || shipmentType == 0);

        return (storageId == 10 || storageId == 11) && (cod == null || cod == 0) && (shipmentType == null || shipmentType == 0);
    }


    /**
     * 判断 是否是 黑猫小包的size
     *
     * @return
     */
    @Override
    public boolean jpostExpressSize(double[] size, Long storageId, Integer cod, Integer shipmentType) {

        return (storageId == 10) && (cod == null || cod == 0) && (shipmentType == null || shipmentType == 0);
    }

    /**
     * //黑猫临时切换成佐川发货
     *
     * @param productDoList
     * @return
     */
    private boolean isSeinoTrack(List<OrderOutputProductDo> productDoList) {
        String s = "4753,4939,5202,5428,7187,7188,8292,8294,8940,11076,11077,11078,11079,12625,12647,12659,"
                + "13288,13414,13593,13594,13905,13924,13925,13967,14517,14606,14607,14859,14860,14861,14862,14863,"
                + "14864,14865,15058,15143,15144,15145,15152,15257,15258,15259,15260,15355,15749,16037,16039,16047,"
                + "12642,12643,12648,12649,12650,12652,12653,12654,12655,12657,12658,13676,13677,13678,13679,13680,13681,12651,15078,15080,"
                + "15082,15083,15084,15085,15086,15087,15088,15089,15090,15091,15092,15093,15094,16660,16661,"
                + "16053,16361,16440,16742,16743,17419";
        List<String> strings = Arrays.stream(s.split(",")).collect(Collectors.toList());
        for (OrderOutputProductDo productDo : productDoList) {
            if (strings.contains(productDo.getProductId() + "")) return true;
        }
        return false;
    }

    /**
     * 获取包裹捆包信息
     *
     * @param productDoList
     * @param storageId
     * @param split         是否分包 true 分包 false 就一个包裹
     * @return
     */
    private List<OrderOutputPackageDetailDo> getPackageSizeInfoCount(List<OrderOutputProductDo> productDoList,
                                                                     boolean split, Long trackId, Long storageId, Long companyId, Map<Long, ProductInfoDo> productmMap) {
        double[] size = new double[4];
        int totalCount = 0;
        int currentCount = 0;
        List<OrderOutputPackageDetailDo> packageDoList = new ArrayList<>();
        for (OrderOutputProductDo productDo : productDoList) {
            totalCount = totalCount + productDo.getCount();
        }
        double[] sizeTemp = new double[]{size[0], size[1], size[2], size[3]};
        double[] sizeLast = new double[4];
        int inCount = 0;
        StringBuilder skuId = new StringBuilder();
        int sum = productDoList.stream().mapToInt(OrderOutputProductDo::getCount).sum();
        int productKind = (int) productDoList.stream().map(OrderOutputProductDo::getProductId).distinct().count();

        //todo 实际是最小边 大于1.5 小于等于3
        //C1518 或者产品在 splitProductIds内    且总数量= 2 则拆单发
        boolean smallFlag = false;
        Double[] rightSmallArr = null;
        if (sum == 2 && (trackId == null || DicBusinessItemConstant.yamatoExpressSmall.equals(trackId))) {
            smallFlag = true;
            double[] packShort = new double[3];
            double[] packMinor = new double[3];
            double packWeight = 0d;

            for (OrderOutputProductDo orderOutputProductDo : productDoList) {
                ProductInfoDo productBean = productmMap.get(orderOutputProductDo.getProductId());
                double[] sizeP = mShipPriceService.getSizeOrderDesc(Double.valueOf(String.valueOf(productBean.getWidth()))
                        , Double.valueOf(String.valueOf(productBean.getHeight())), Double.valueOf(String.valueOf(productBean.getLength())));
                packShort[0] = sizeP[0];
                packShort[1] = sizeP[1];
                packMinor[0] = sizeP[0];
                packMinor[2] = sizeP[2];
                packWeight = packWeight + productBean.getWeight() * orderOutputProductDo.getCount();
                for (int i = 0; i < orderOutputProductDo.getCount(); i++) {
                    packShort[2] = packShort[2] + sizeP[2];
                    packMinor[1] = packMinor[1] + sizeP[1];
                }
                if ((sizeP[0] < 32.2d && sizeP[1] < 22.10d && sizeP[2] < 3.1d && productBean.getWeight() < 1)) {
                    continue;
                }
                smallFlag = false;
//                break;
            }
            packShort = mShipPriceService.getSizeOrderDesc(packShort[0], packShort[1], packShort[2]);
            packMinor = mShipPriceService.getSizeOrderDesc(packMinor[0], packMinor[1], packMinor[2]);
            if (smallFlag && ((packShort[2] < 3.1d && packShort[0] < 32.2) || (packMinor[1] < 22.10d && packMinor[0] < 32.2)) && packWeight < 1) {
                smallFlag = false;
                if (packShort[2] < 3.1d) {
                    rightSmallArr = new Double[]{packShort[0], packShort[1], packShort[2]};
                } else {
                    rightSmallArr = new Double[]{packMinor[0], packMinor[1], packMinor[2]};
                }
            }
        }
        boolean splitFlag = smallFlag;
        for (int j = 0; j < productDoList.size(); j++) {
            OrderOutputProductDo productDo = productDoList.get(j);
            ProductInfoDo productBean = productmMap.get(productDo.getProductId());
            if (productDo.getCount() / productBean.getCasePack() > 0 && productBean.getCasePack() != 1) {
                OrderInputProductDo orderInputProductDo = inputOrderProductDao.selectOne(new LambdaQueryWrapper<OrderInputProductDo>().eq(OrderInputProductDo::getProductId, productBean.getId())
                        .eq(OrderInputProductDo::getCount, productBean.getCasePack()).orderByDesc(OrderInputProductDo::getId).last("limit 1"));
                OrderOutputPackageDetailDo packageDo = new OrderOutputPackageDetailDo();
                if (orderInputProductDo != null) {
                    OrderInputPackageDo orderInputPackageDo = inputOrderPackageDao.selectById(orderInputProductDo.getPackageId());
                    packageDo.setLength(new BigDecimal(orderInputPackageDo.getPackageLenght()).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    packageDo.setWidth(new BigDecimal(orderInputPackageDo.getPackageWidth()).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    packageDo.setHeight(new BigDecimal(orderInputPackageDo.getPackageHeight()).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    packageDo.setWeight(new BigDecimal(orderInputPackageDo.getPackageWeight()).setScale(2, RoundingMode.HALF_UP).doubleValue());
                } else {
                    double[] doubles = mShipPriceService.countSameSkuSizeNew(sizeTemp, productBean, productBean.getCasePack().intValue());
                    packageDo.setLength(doubles[0]);
                    packageDo.setWidth(doubles[1]);
                    packageDo.setHeight(doubles[2]);
                    packageDo.setWeight(doubles[3]);
                }
                packageDo.setInCount(productBean.getCasePack().intValue());
                for (int i = 0; i < productBean.getCasePack(); i++) {
                    skuId.append(productDo.getProductId()).append(",");
                }
                packageDo.setInSkuId(skuId.toString());
                packageDo.setMaterialId(-1L);
                skuId = new StringBuilder();
                for (long i = 0; i < productDo.getCount() / productBean.getCasePack(); i++) {
                    OrderOutputPackageDetailDo packageDetailDo = new OrderOutputPackageDetailDo();
                    BeanUtils.copyProperties(packageDo, packageDetailDo);
                    packageDoList.add(packageDetailDo);
                    currentCount = currentCount + productBean.getCasePack().intValue();
                }
                if (productDo.getCount() % productBean.getCasePack() >= productBean.getCasePack() / 2) {
                    OrderOutputPackageDetailDo packageDetailDo = new OrderOutputPackageDetailDo();
                    BeanUtils.copyProperties(packageDo, packageDetailDo);
                    int inCount1 = (int) (productDo.getCount() % productBean.getCasePack());
                    packageDetailDo.setInCount(inCount1);
                    for (int i = 0; i < inCount1; i++) {
                        skuId.append(productDo.getProductId()).append(",");
                    }
                    packageDetailDo.setInSkuId(skuId.toString());
                    skuId = new StringBuilder();
                    packageDoList.add(packageDetailDo);
                } else if (productDo.getCount() % productBean.getCasePack() > 0) {
                    int lastPackCount = (int) (productDo.getCount() % productBean.getCasePack()) + productBean.getCasePack().intValue();
                    PackageMinTrilateralSum.PackageInfo packageInfo = PackageMinTrilateralSum.caleMinTrilateralSum(lastPackCount,
                            Double.valueOf(String.valueOf(productBean.getWidth()))
                            , Double.valueOf(String.valueOf(productBean.getHeight())), Double.valueOf(String.valueOf(productBean.getLength())));
                    List<Double> doubles = packageInfo.getPackageSizeList().iterator().next();
                    OrderOutputPackageDetailDo packageDetailDo = packageDoList.get(packageDoList.size() - 1);
                    packageDetailDo.setLength(doubles.get(0));
                    packageDetailDo.setWidth(doubles.get(1));
                    packageDetailDo.setHeight(doubles.get(2));
                    packageDetailDo.setWeight(Double.valueOf(String.valueOf(productBean.getWeight() * lastPackCount)));
                    packageDetailDo.setInCount(lastPackCount);
                    currentCount = currentCount + lastPackCount - productBean.getCasePack().intValue();
                    for (int i = 0; i < lastPackCount; i++) {
                        skuId.append(productDo.getProductId()).append(",");
                    }
                    packageDetailDo.setInSkuId(skuId.toString());
                    skuId = new StringBuilder();
                }
            } else {
                if ((companyId.intValue() == 591 || companyId.intValue() == 410 || companyId.intValue() == 201) && !splitFlag) {

                    List<Double> doubles = null;
                    if (rightSmallArr != null && productKind == 1) {
                        doubles = Arrays.asList(rightSmallArr);
                    } else {
                        PackageMinTrilateralSum.PackageInfo packageInfo = PackageMinTrilateralSum.caleMinTrilateralSum(productDo.getCount(), Double.valueOf(String.valueOf(productBean.getWidth()))
                                , Double.valueOf(String.valueOf(productBean.getHeight())), Double.valueOf(String.valueOf(productBean.getLength())));
                        doubles = packageInfo.getPackageSizeList().iterator().next();
                    }
                    // sizeTemp = new double[]{doubles.get(0), doubles.get(1), doubles.get(2), productDo.getCount() * productBean.getWeight()};
                    if ((currentCount > 0 && verifyMaxSize(mShipPriceService.countSameSkuSizeNew(sizeTemp, doubles.get(0), doubles.get(1), doubles.get(2),
                            productDo.getCount() * productBean.getWeight(), 1), false, storageId, companyId, trackId))) {
                        OrderOutputPackageDetailDo packageDo = new OrderOutputPackageDetailDo();
                        packageDo.setLength(sizeTemp[0]);
                        packageDo.setWidth(sizeTemp[1]);
                        packageDo.setHeight(sizeTemp[2]);
                        packageDo.setWeight(sizeTemp[3]);
                        packageDo.setInCount(inCount);
                        packageDo.setInSkuId(skuId.toString());
                        packageDoList.add(packageDo);
                        skuId = new StringBuilder();
                        size = new double[]{doubles.get(0), doubles.get(1), doubles.get(2), productDo.getCount() * productBean.getWeight()};
                        sizeTemp[0] = size[0];
                        sizeTemp[1] = size[1];
                        sizeTemp[2] = size[2];
                        sizeTemp[3] = size[3];
                        for (int i = 0; i < productDo.getCount(); i++) {
                            skuId.append(productDo.getProductId()).append(",");
                        }
                    } else {
                        //跟上一个同一包裹
                        for (int i = 0; i < productDo.getCount(); i++) {
                            skuId.append(productDo.getProductId()).append(",");
                        }
                        sizeTemp = mShipPriceService.countSameSkuSizeNew(sizeTemp, doubles.get(0), doubles.get(1), doubles.get(2),
                                productDo.getCount() * productBean.getWeight(), 1);
                    }
                    currentCount = currentCount + productDo.getCount();
                } else {
                    for (int i = 0; i < productDo.getCount(); i++) {
                        boolean isMulti = false;
                        double[] sizeP = mShipPriceService.getSizeOrderDesc(Double.valueOf(String.valueOf(productBean.getWidth()))
                                , Double.valueOf(String.valueOf(productBean.getHeight())), Double.valueOf(String.valueOf(productBean.getLength())));
                        if ((sizeLast[0] != 0 && sizeLast[0] != sizeP[0]) || (sizeLast[1] != 0 && sizeLast[1] != sizeP[1])) {
                            //如果当前SKU和上一个SKU长宽 边不等，则不能捆包，返回true
                            isMulti = true;
                        }
                        if (i + j > 0 && (verifyMaxSize(mShipPriceService.countSameSkuSizeNew(sizeTemp, productBean, 1), isMulti, storageId, companyId, trackId)
                                || productBean.getSupPackage() == 0 || splitFlag)) {
                            //新创建一个包裹
                            OrderOutputPackageDetailDo packageDo = new OrderOutputPackageDetailDo();
                            packageDo.setLength(sizeTemp[0]);
                            packageDo.setWidth(sizeTemp[1]);
                            packageDo.setHeight(sizeTemp[2]);
                            packageDo.setWeight(sizeTemp[3]);
                            packageDo.setInCount(inCount);
                            packageDo.setInSkuId(skuId.toString());
                            packageDoList.add(packageDo);
                            size = new double[4];
                            size = mShipPriceService.countSameSkuSize(size, productDo.getProductId(), 1);
                            sizeTemp[0] = size[0];
                            sizeTemp[1] = size[1];
                            sizeTemp[2] = size[2];
                            sizeTemp[3] = size[3];
                            inCount = 1;
                            skuId = new StringBuilder();
                            skuId.append(productDo.getProductId()).append(",");
                        } else {
                            //跟上一个同一包裹
                            inCount++;
                            skuId.append(productDo.getProductId()).append(",");
                            sizeTemp = mShipPriceService.countSameSkuSizeNew(sizeTemp, productBean, 1);
                        }
                        sizeLast = new double[]{sizeP[0], sizeP[1], sizeP[2], productBean.getWeight()};

                        currentCount++;
                    }
                }
                //一单一件直接创建detail
                if (currentCount == totalCount && (sizeTemp != null && sizeTemp[0] > 0 && sizeTemp[1] > 0 && sizeTemp[2] > 0)) {
                    OrderOutputPackageDetailDo packageDo = new OrderOutputPackageDetailDo();
                    packageDo.setLength(sizeTemp[0]);
                    packageDo.setWidth(sizeTemp[1]);
                    packageDo.setHeight(sizeTemp[2]);
                    packageDo.setWeight(sizeTemp[3]);
                    packageDo.setInCount(inCount);
                    packageDo.setInSkuId(skuId.toString());
                    packageDoList.add(packageDo);
                }
            }
        }
        //设置 耗材长宽高
        for (OrderOutputPackageDetailDo packageDetailDo : packageDoList) {
            this.setPackageDetailMaterialLength(packageDetailDo, trackId, storageId, companyId);
        }
        return packageDoList;
    }

    /**
     * 不捆包产品清单
     *
     * @param productId
     * @return
     */
    private boolean inNoPackageProductList(Long productId) {
        List<Long> productList = new ArrayList<>();
        productList.addAll(Arrays.asList(new Long[]{9869L, 13185L, 11076L, 11077L, 11615L, 12625L, 13288L, 13905L, 13924L, 13925L, 13931L, 15260L, 15259L, 15258L, 15257L, 14865L, 14864L, 14863L, 14862L, 14861L, 14860L, 14859L, 14858L}));
        if (productId == null) return true;
        return productList.contains(productId);
    }
    //
    // private boolean verifyMaxSize(List<OrderOutputProductDo> productDoList, double[] size, Long storageId) {
    //     double[] sizeLast = new double[4];
    //     boolean iMulti = false;
    //     for (OrderOutputProductDo productDo : productDoList) {
    //         ProductInfoDo productBean = productInfoDao.selectById(productDo.getProductId());
    //         if (productBean == null) return false;
    //         double[] sizeP = mShipPriceService.getSizeOrderDesc(productBean.getWidth(), productBean.getHeight(), productBean.getLength());
    //         if ((productDoList.size() > 0 || productDo.getCount() > 0) && productBean.getSupPackage() == 0) {
    //             iMulti = true;
    //         } else if ((sizeLast[0] != 0 && sizeLast[0] != sizeP[0]) || (sizeLast[1] != 0 && sizeLast[1] != sizeP[1])) {
    //             //如果当前SKU和上一个SKU长宽 边不等，则不能捆包，返回true
    //             iMulti = true;
    //         }
    //         sizeLast = new double[]{sizeP[0], sizeP[1], sizeP[2], productBean.getWeight()};
    //     }
    //     return verifyPackageMaxSize(size, iMulti, storageId);
    // }


    private boolean verifyMaxSize(double[] size, boolean isMulti, Long storageId, Long companyId, Long trackId) {
        if (companyId != null & trackId != null && companyId.intValue() == 84
                && (DicBusinessItemConstant.yamatoExpressA.equals(trackId) || DicBusinessItemConstant.yamatoExpressSLS.equals(trackId))) {
            //特殊情况
            return size[3] > 0.1;
        } else if (companyId != null && (companyId.intValue() == 410 || companyId.intValue() == 591)) {
            return size[0] + size[1] + size[2] > 120 || size[3] > 25;
        } else if (companyId != null && (companyId.intValue() == 566)) {
            return size[0] + size[1] + size[2] > 140 || size[3] > 25;
        } else if (companyId != null && (companyId.intValue() == 1) && !isMulti) {
            //特殊情况
            return size[0] + size[1] + size[2] > SysConstant.OUT_MAX_SINGLE_PACKAGE_SIZE || size[3] > SysConstant.OUT_MAX_SINGLE_PACKAGE_WEIGHT;
        } else {
            return size[0] + size[1] + size[2] > SysConstant.OUT_MAX_MUTIL_PACKAGE_SIZE || size[3] > SysConstant.OUT_MAX_MUTIL_PACKAGE_WEIGHT;
        }
    }

    //
    // private boolean verifyPackageMaxSize(double[] size, boolean isMulti, Long storageId ,Long companyId) {
    //     if (companyId!=null&&companyId.intValue()==1) {
    //         //特殊情况
    //         return size[0] + size[1] + size[2] > SysConstant.OUT_MAX_SINGLE_PACKAGE_SIZE || size[3] > SysConstant.OUT_MAX_SINGLE_PACKAGE_WEIGHT;
    //     }else {
    //         return size[0] + size[1] + size[2] > SysConstant.OUT_MAX_MUTIL_PACKAGE_SIZE || size[3] > SysConstant.OUT_MAX_MUTIL_PACKAGE_WEIGHT;
    //     }
    // }

    /**
     * 根据顾客SKU查找productId
     *
     * @param sellerSku1
     * @param companyId
     * @return
     */
    private Long getProductId(String sellerSku1, Long companyId) {
        final String sellerSku = sellerSku1.trim().replaceAll("\\n", "").replaceAll("　", "");
        LambdaQueryWrapper<ProductInfoDo> productWrapper = new LambdaQueryWrapper();
        productWrapper.eq(ProductInfoDo::getCompanyId, companyId);
        productWrapper.and(product -> {
            product.eq(ProductInfoDo::getCommoditySku, sellerSku)
                    .or()
                    .eq(ProductInfoDo::getStorageSku, sellerSku);
        });
        productWrapper.last("limit 1");
        ProductInfoDo productInfoDo = productInfoDao.selectOne(productWrapper);
        if (productInfoDo == null) {
            QueryWrapper skuWrapper = new QueryWrapper();
            skuWrapper.eq("sub_sku", sellerSku);
            skuWrapper.eq("company_id", companyId);
            ProductSkuMapDo productSkuMapDo = productSkuMapDao.selectOne(skuWrapper);
            if (productSkuMapDo == null) throw new BizExceptionI18(SysConstant.Product_NotFound, sellerSku);
            return productSkuMapDo.getProductInfoId();
        } else {
            return productInfoDo.getId();
        }
    }

    private Long getSubProductId(String sellerSku, Long companyId) {
        QueryWrapper skuWrapper = new QueryWrapper();
        skuWrapper.eq("sub_sku", sellerSku);
        skuWrapper.eq("company_id", companyId);
        ProductSkuMapDo productSkuMapDo = productSkuMapDao.selectOne(skuWrapper);
        if (productSkuMapDo == null) return 0L;
        return productSkuMapDo.getProductInfoId();
    }

    @Override
    public OrderOutputDetailRes getTrackInfo(String orderNo, Long companyId) {
        Long orderId = 0L;
        OrderOutputDo entityDo = null;
        if (StringUtils.isEmpty(orderNo)) throw new BizExceptionI18(SysConstant.Order_Detail_Notfound);
        if (orderNo.startsWith("OT")) {
            orderId = Long.parseLong(orderNo.substring(10));
            entityDo = dao.selectById(orderId);
        } else {
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.eq("order_no", orderNo);
            wrapper.eq("company_id", companyId);
            wrapper.last("limit 1");
            entityDo = dao.selectOne(wrapper);
        }
        OrderOutputDetailRes res = new OrderOutputDetailRes();
        if (entityDo == null) throw new BizExceptionI18(SysConstant.Order_Detail_Notfound);
        BeanUtils.copyProperties(entityDo, res);
        return handlerDetailAfter(entityDo, res);
    }

    @Override
    public SingleResult orderRepeat(Long id, Long currentUserId, Long companyId) {
        OrderOutputDo orderOutputDo = dao.selectById(id);
        if (orderOutputDo == null) throw new BizExceptionI18(SysConstant.Order_Detail_Notfound);
        OrderOutputAddReq orderOutputDoNew = new OrderOutputAddReq();
        BeanUtils.copyProperties(orderOutputDo, orderOutputDoNew);
        orderOutputDoNew.setSendDate(new Date());
        orderOutputDoNew.setShipFee(0);
        orderOutputDoNew.setTrackId(null);
//        orderOutputDoNew.setStorageId(0L);
        orderOutputDoNew.setDeliveryTime("");
        orderOutputDoNew.setDeliveryDate("");
        orderOutputDoNew.setOrderNo(orderOutputDoNew.getOrderNo() + "-R");
        orderOutputDoNew.setOperateFee(0);
        LambdaQueryWrapper<OrderOutputPackageDo> packageDoWrapper = new LambdaQueryWrapper<>();
        packageDoWrapper.eq(OrderOutputPackageDo::getOrderOutputId, orderOutputDo.getId());
        List<OrderOutputPackageDo> packageDoList = packageDao.selectList(packageDoWrapper);
        List<OrderOutputPackageAddReq> packageAddReqList = new ArrayList<>();
        if (packageDoList == null) throw new BizExceptionI18(SysConstant.Order_Package_Notfound);
        for (OrderOutputPackageDo packageDo : packageDoList) {
            OrderOutputPackageAddReq packageAddReq = new OrderOutputPackageAddReq();
            BeanUtils.copyProperties(packageDo, packageAddReq);
            LambdaQueryWrapper<OrderOutputProductDo> productDoWrapper = new LambdaQueryWrapper<>();
            productDoWrapper.eq(OrderOutputProductDo::getPackageId, packageDo.getId());
            List<OrderOutputProductDo> productDoList = productDao.selectList(productDoWrapper);
            List<OrderOutputProductAddReq> productAddReqList = new ArrayList<>();
            if (productDoList.size() < 1) throw new BizExceptionI18(SysConstant.Product_Info_NotNull);
            for (OrderOutputProductDo productDo : productDoList) {
                OrderOutputProductAddReq productDooNew = new OrderOutputProductAddReq();
                BeanUtils.copyProperties(productDo, productDooNew);
                productAddReqList.add(productDooNew);
            }
            packageAddReq.setProductList(productAddReqList);
            packageAddReqList.add(packageAddReq);
        }
        orderOutputDoNew.setPackageList(packageAddReqList);

        String value = add(orderOutputDoNew, currentUserId);
        if (value == null) {
            return SingleResult.success();
        } else {
            return SingleResult.failure(value);
        }
    }

    @Override
    public SingleResult cancelOrder(String outOrderNumber, Long userId) {
        LambdaQueryWrapper<OrderOutputDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderOutputDo::getOrderOutputNumber, outOrderNumber);
        OrderOutputDo entityDo = baseMapper.selectOne(wrapper);
        if (entityDo == null) throw new BizExceptionI18(SysConstant.Order_Detail_Notfound);

        cutoff(entityDo.getId(), userId, entityDo.getCompanyId());
//                throw new BizExceptionI18(SysConstant.ORDER_HAS_DEAL);
        return SingleResult.success();
    }

    @Override
    public List<IdAndNameEntity> getTrackWay() {
//        List<DicBusinessItemDo> itemDoList = dicBusinessItemDao.selectList(new QueryWrapper<DicBusinessItemDo>().eq("dic_business_id", DicBusinessConstant.trackCompany));
//        return itemDoList.stream().map(dicBusinessItemDo -> {
//            return new IdAndNameEntity(dicBusinessItemDo.getId().intValue(), dicBusinessItemDo.getDicItemValue());
//        }).collect(Collectors.toList());
        return this.getTrackList();
    }

    @Override
    public void updateOrderOutCheckStatus() {
        LambdaQueryWrapper<OrderOutputDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderOutputDo::getStatus, DicBusinessItemConstant.outCreateState);
        wrapper.gt(OrderOutputDo::getSendDate, TimeUtils.getCurrentDateFormat(-7));
        wrapper.lt(OrderOutputDo::getCreateTime, TimeUtils.getAfterTimeFormat(TimeUtils.YYYYMMddHHmmss, 0, -10));
        List<OrderOutputDo> entityDoList = baseMapper.selectList(wrapper);
        for (OrderOutputDo entityDo : entityDoList) {
            LambdaQueryWrapper<OrderOutputProductDo> productDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            productDoLambdaQueryWrapper.eq(OrderOutputProductDo::getOrderId, DicBusinessItemConstant.outCreateState);
            List<OrderOutputProductDo> productDoList = productDao.selectList(productDoLambdaQueryWrapper);
            if (productDoList.size() < 1) continue;
            List<OrderOutputProductAddReq> collect = productDoList.stream().map(new Function<OrderOutputProductDo, OrderOutputProductAddReq>() {
                @Override
                public OrderOutputProductAddReq apply(OrderOutputProductDo orderOutputProductDo) {
                    OrderOutputProductAddReq addReq = new OrderOutputProductAddReq();
                    addReq.setProductId(orderOutputProductDo.getProductId());
                    addReq.setCommoditySku(orderOutputProductDo.getSku());
                    addReq.setCount(orderOutputProductDo.getCount());
                    return addReq;
                }
            }).collect(Collectors.toList());
            String value = checkOrderNo(entityDo.getOrderNo().trim(), entityDo.getCompanyId(), collect);
            if (value != null) {
                baseMapper.deleteById(entityDo.getId());
                continue;
            }
            String value1 = handlerAddAfter(entityDo, null);
            if (value1 != null) {
                //todo 加到队列订单，等待处理
            }
            //日志操作
            if (value1 == null) {
                operateRecordDao.operateAddRecord(SysConstant.OPERATE_SYSTEM_CHECK_ORDER, entityDo.getId(), entityDo.getCreateBy(), 3);
//                operateRecord("系统自动审核", entityDo.getId(), entityDo.getCreateBy());
            } else {
                operateRecordDao.operateAddRecord(SysConstant.OPERATE_SYSTEM_ERROR_ORDER, entityDo.getId(), entityDo.getCreateBy(), 3);
//                operateRecord("系统自动异常", entityDo.getId(), entityDo.getCreateBy());
            }
        }
    }

    @Override
    public void exportShippingLabelPdfByOutputId(Long[] ids, HttpServletResponse response) {
        /*Collection<OrderOutputDo> dataList = this.listByIds(Arrays.asList(ids));
        List<String> pno = dataList.stream().map(OrderOutputDo::getOrderNo).collect(Collectors.toList());
        List<OrderAmazonVdfDo> vdfOrderList = vdfService.list(
                Wrappers.<OrderAmazonVdfDo>lambdaQuery()
                        .in(OrderAmazonVdfDo::getPurchaseOrderNumber, pno)
        );
        List<Long> vdfId = vdfOrderList.stream().map(OrderAmazonVdfDo::getId).collect(Collectors.toList());
        if (vdfId.size() != pno.size()) {
            response.setHeader("Content-Type", "application/json");
            //找到第三方订单
            pno.removeAll(vdfOrderList.stream().map(OrderAmazonVdfDo::getPurchaseOrderNumber).collect(Collectors.toList()));
            response.setHeader("thirdPartyOrder", JSONArray.toJSONString(pno));
        }
        vdfService.exportShippingLabelPdf(vdfId, response);*/
    }

    @Override
    public Object updateStock(OrderOutputUpdateReq req, Long userId) {
        OrderOutputDo outputDo = dao.selectById(req.getId());
        if (outputDo == null) throw new BizExceptionI18(SysConstant.Order_Detail_Notfound);
        if (outputDo.getStatus() > DicBusinessItemConstant.outCreateCheckState) {
            throw new BizExceptionI18(SysConstant.Order_HadDeal);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("storage", storageService.getJpList());
        map.put("region", regionService.getList(new HashMap<>()));
        HashMap<String, String> map1 = new HashMap<>();
        map1.put("company_id", outputDo.getCompanyId() + "");
        map.put("shopList", shopService.getList(map1));
        OrderOutputDetailRes res = new OrderOutputDetailRes();
        outputDo.setShopId(req.getShopId());
        outputDo.setStorageId(req.getStorageId());
        BeanUtils.copyProperties(outputDo, res);
        map.put("detail", handlerDetailAfter(outputDo, res));
        return SingleResult.success(map);
    }


    @Override
    public Long getProductId(String sellerSku, Long companyId, int type) {
        sellerSku.trim().replaceAll("\\n", "").replaceAll("　", "");
        LambdaQueryWrapper<ProductInfoDo> productWrapper = new LambdaQueryWrapper();
        productWrapper.eq(ProductInfoDo::getCompanyId, companyId);
        productWrapper.and(product -> {
            product.eq(ProductInfoDo::getCommoditySku, sellerSku).or().eq(ProductInfoDo::getStorageSku, sellerSku);
        });
        ProductInfoDo productInfoDo = productInfoDao.selectOne(productWrapper);
        if (productInfoDo == null) {
            QueryWrapper skuWrapper = new QueryWrapper();
            skuWrapper.eq("sub_sku", sellerSku);
            skuWrapper.eq("company_id", companyId);
            ProductSkuMapDo productSkuMapDo = productSkuMapDao.selectOne(skuWrapper);
            if (productSkuMapDo == null) {
                if (type == 1) {
                    throw new BizExceptionI18(SysConstant.Product_NotFound, sellerSku);
                } else {
                    return null;
                }
            }
            return productSkuMapDo.getProductInfoId();
        } else {
            return productInfoDo.getId();
        }
    }


    @Override
    public Collection<String> addTiktokList(List<OrderOutputAddReq> orderOutputAddReqList, Long userId) {
        List<String> failedOrderids = new ArrayList<>();
        List<String> successOrderids = new ArrayList<>();
        for (OrderOutputAddReq outputAddReq : orderOutputAddReqList) {
            String value = add(outputAddReq, userId);
            if (value != null) {
                failedOrderids.add(value);
            } else {
                if (StringUtils.isNotBlank(outputAddReq.getPlatformNumber())) {
                    successOrderids.add(outputAddReq.getPlatformNumber());
                    if (successOrderids.size() > 0)
                        orderTiktokDao.batchUpdateIsSendOutByIds(successOrderids);
                }
            }
        }


        return failedOrderids;
    }



  /*  private void handleMarkPackageShipped(List<String> successOrderids) {
        //调用标记包裹发送接口
        List<Map<String, List<OrderOutputPackageDetailDo>>> orderRequstsList = new ArrayList<>();
        for (String orderId : successOrderids) {
            List<OrderOutputPackageDetailDo> packageDetailDos = new ArrayList<>();
            Map<String, List<OrderOutputPackageDetailDo>> orderRequests = new HashMap<>();
            orderRequests.put(orderId, packageDetailDos);
            orderRequstsList.add(orderRequests);
        }
        tiktokOrderService.markPackageAsShipped(orderRequstsList);
    }*/
}
